#spring #spring-boot #spring-restcontroller
Вопрос:
1. Контекст
Клиенту необходимо отправить запрос на ОТДЫХ, чтобы данные формы могли храниться на сервере. Вот пример формы, которую необходимо отправить:
Также имейте в виду, что компонент dropzone будет изменен таким образом, чтобы он также запрашивал необязательное небольшое описание для каждого файла, который пользователь будет загружать.
Таким образом, в этом примере сервер получит:
- UseCase (строка)
- Файлы : Один или несколько файлов
- Описание
Сервер настроен с помощью Spring-Boot, @RestController, и библиотека Jakson обрабатывает сериализацию/десериализацию.
2. Требования
Операция должна быть атомарной
Если исключение возникает до завершения всей операции, ни одна из его данных не должна сохраняться на сервере. По этой причине до сих пор я внимательно следил за решениями, связанными с одним запросом, поскольку тогда всю операцию будет легче откатить, если что-то пойдет не так.
Файл должен быть напрямую связан с соответствующим описанием
Многие из решений, которые я нашел, используют простой массив файлов. Не похоже, что это позволит мне сохранить связь между файлом и его описанием.
Держите количество параметров в контроллере как можно меньшим
For the purpose of this post I have simplified the examples. But in reality the form will send way more data than a string and some files.
For that reason I’d like that the signature of the function stays as simple as possible.
3. Question
I have checked the documentation, many tutorials and there are many possibilities to implement this but they are often a bit off considering my 3 requirements.
Considering that, what would be the best way to handle this according to you?
Please give me an example of how :
- You would write the controller’s signature.
- You would format the front-end data (For instance what ‘Content-Type’ header should I use).
Here is an example of the controller I’m using (don’t mind the attempt I’ve done).
@PostMapping(path = "/form/{formId}/data", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public void postData(@PathVariable Long formId, @Valid @ModelAttribute NewFormData formData) throws IOException {
//Do some stuff like calling the form's service to process the request
}
As you can see I’m trying to make Spring deserialize the received data in a NewFormData
object. That way it makes it easier to work with the many data sent by the form.
Here is a example of the class I used as the parameter of the controller that will contain the form’s data:
public class NewFormData {
/*
* Form's data that will be deseriliazed
*/
NewTextBoxData textBoxData;
List<NewFileData> fileData;
private static class NewData {
/**
* If a PUT request is sent later I will have to modified the existing data in DB. This value will either be an int or null if it's not persisted yet.
*/
public Integer Id;
}
public static class NewTextBoxData extends NewData{
public String value;
}
public static class NewFileData extends NewData{
public String description;
public MultipartFile file;
}
}