Как правильно обработать POST запрос Spring Boot через JpaRepository
Трудность вот в чём; в POST запросе на сервер передаётся не только json добавляемого в базу объекта, но ещё и файл (картинка). Я добавляю в тело запроса объект FormData, у него два параметра, один с json другой с файлом.
При обработке таког запроса в контроллере, через аннотацию параметра @RequestParam, с получением файла проблем нет, а вот с получением объекта из json есть. Раньше когда в запросе был только json использовался @RequestBody и Spring сам парсил джейсоновскую строку в нужный объект, из @RequestParam он этого делать не хочет (или я что-то не то делаю).
Понятно что можно распарсить и создать объект самому вручную. Но опять же вопрос, как правильно это делать? Можно обойтись только библиотекой Spring или нужно ставить ещё скажем Gson?
Ответы (1 шт):
Controller
@PostMapping(value = "/createSubject")
public void createSubject(@RequestPart(value = "file", required = false) Collection<MultipartFile> files, @RequestPart("subject") String subjectInString) {
subjectService.createSubject(subjectInString, files);
}
Вместо Collection можно использовать просто MultipartFile
Service
@Transactional
@Override
public void createSubject(String subjectInString, Collection<MultipartFile> files) {
try {
ObjectMapper objectMapper = new ObjectMapper();
Subject subject = objectMapper.readValue(subjectInString, Subject.class);
if (subject != null) {
if (!subjectRepository.existsByNameAndType(subject.getName(), subject.getType())) {
if (files != null && !files.isEmpty())
addFilesToSubject(files, subject);
subjectRepository.save(subject);
} else {
throw new SubjectAlreadyExistsException(subject.getName(), subject.getType().name());
}
} else {
throw new SubjectIsNullException();
}
} catch (IOException e) {
throw new SubjectIsNullException();
}
}
Пример клиента Angular
Service
public createSubject(subject: Subject, files: File[]): Observable<any>{
let data = new FormData();
let headers = new HttpHeaders();
headers.append('Content-Type','multipart/form-data');
this.appendFiles(files, data);
data.append('subject', JSON.stringify(subject));
return this.http.post(API_URL + 'subject/createSubject', data, {headers: headers});
}
private appendFiles(files: File[], data:FormData){
for (let file of files) {
data.append('file', file);
}
}