Я делаю приложение REST для весенней загрузки. Я пытаюсь создать контроллер загрузки многокомпонентной формы, который будет обрабатывать данные формы и загрузку файла вместе. Это мой код контроллера на данный момент:
@RequestMapping(value = "", method = RequestMethod.POST, headers = "Content-Type=multipart/form-data")
@PreAuthorize("hasRole('ROLE_MODERATOR')")
@ResponseStatus(HttpStatus.CREATED)
public void createNewObjectWithImage(
/*@RequestParam(value = "file", required=true) MultipartFile file,
@RequestParam(value = "param_name_1", required=true) final String param_name_1,
@RequestParam(value = "param_name_2", required=true) final String param_name_2,
@RequestParam(value = "param_name_3", required=true) final String param_name_3,
@RequestParam(value = "param_name_4", required=true) final String param_name_4,
@RequestParam(value = "param_name_5", required=true) final String param_name_5*/
@ModelAttribute ModelDTO model,
BindingResult result) throws MyRestPreconditionsException {
//ModelDTO model = new ModelDTO(param_name_1, param_name_2, param_name_3, param_name_4, param_name_5);
modelValidator.validate(model, result);
if (result.hasErrors()){
MyRestPreconditionsException ex = new MyRestPreconditionsException(
"Model creation error",
"Some of the elements in the request are missing or invalid");
ex.getErrors().addAll(
result.getFieldErrors().stream().map(f -> f.getField()+" - "+f.getDefaultMessage()).collect(Collectors.toList()));
throw ex;
}
// at the moment, model has a MultipartFile property
//model.setImage(file);
modelServiceImpl.addNew(model);
}
Я пробовал как с аннотацией @ModelAttribute, так и с параметрами отправки запроса, но оба эти метода не дали результата.
Это запрос, который я отправляю:
---------------------------acebdf13572468
Content-Disposition: form-data; name = "file"; filename = "mint.jpg"
Content-Type: image/jpeg
<@INCLUDE *C:\Users\Lazaruss\Desktop\mint.jpg*@>
---------------------------acebdf13572468
Content-Disposition: form-data; name=”param_name_1”
string_value_1
---------------------------acebdf13572468
Content-Disposition: form-data; name=”param_name_2”
string_value_2
---------------------------acebdf13572468
Content-Disposition: form-data; name=”param_name_3”
string_value_3
---------------------------acebdf13572468
Content-Disposition: form-data; name=”param_name_4”
string_value_4
---------------------------acebdf13572468
Content-Disposition: form-data; name=”param_name_5”
string_value_5
---------------------------acebdf13572468--
Мое приложение не имеет состояния и использует весеннюю безопасность с полномочиями. В свой пакет безопасности я включил класс AbstractSecurityWebApplicationInitializer
public class SecurityApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
@Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
insertFilters(servletContext, new MultipartFilter());
}
}
Я также использую StandardServletMultipartResolver в своем классе @Configuration
И в свой WebInitializer я добавляю этот код:
MultipartConfigElement multipartConfigElement = new MultipartConfigElement("/tmp",
3 * 1024 * 1024, 6 * 1024 * 1024, 1 * 512 * 1024);
apiSR.setMultipartConfig(multipartConfigElement);
Когда я пытаюсь использовать контроллер с закомментированным кодом (аннотации @RequestParams), я получаю ошибку 404 not found. И когда я пытаюсь использовать контроллер с аннотацией @ModuleAttribute, объект модели пуст.
Я использую скрипач




У меня была аналогичная проблема. Если вы хотите отправить Object + Multipart. Вы должны (или, по крайней мере, я не знаю другого решения) сделать свой контроллер таким:
public void createNewObjectWithImage(@RequestParam("model") String model, @RequestParam(value = "file", required = false) MultipartFile file)
А затем: Преобразуйте строку в свой объект, используя:
ObjectMapper mapper = new ObjectMapper();
ModelDTO modelDTO = mapper.readValue(model, ModelDTO.class);
А в Почтальоне его можно отправить так:

Можете ли вы тогда отметить это как правильный ответ? :) @Lazaruss
Решил мою проблему
@CrazySabbath Это совсем не хакерство, о чем ты вообще говоришь?
@prettyvoid прошло много времени с тех пор, как я написал этот комментарий, но я думаю, что причина в том, что нужно десериализовать объект самостоятельно. В целом вы правы, это не хакерство. Мне просто не совсем понравился ответ, думаю, мне следовало подобрать слова по-другому.
что делать, если у вас есть более одного файла для загрузки с помощью одной и той же формы, как это сделать?
@leeCoder Я не тестировал его, но постараюсь ожидать, что в вашем методе будут файлы List <Multipart>, я думаю, он должен работать.
Кажется, этот подход работает, но я не могу применять к нему настраиваемые валидаторы ограничений.
может получать объекты и файлы
@PostMapping(value = "/v1/catalog/create", consumes = MediaType.MULTIPART_FORM_DATA_VALUE )
public void createNewObjectWithImage(
@RequestPart ModelTO modelTO,
@RequestPart MultipartFile image)
МодельТО
public class ModelTO {
private String name;
public ModelTO() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
и пример завитка:
curl -X POST "https://your-url.com/v1/catalog/create" -H "accept: application/json;charset=UTF-8" -H "Content-Type: multipart/form-data" -F "image=@/pathtoimage/powerRager.jpg;type=image/jpeg" -F "modelTO = {\"name\":\"White\"};type=application/json;charset=utf-8"
Почтальон и другое программное обеспечение не поддерживает отправку типа приложения / json для параметров формы.
Почтальон поддерживает отправку типа контента. Просто нажмите ... и проверьте тип содержимого.
Какой у вас внешний клиент? Как отправить запрос.