receive mvc multipartresolver multipartfile spring spring-mvc multipart multipartform-data

mvc - Spring Controller @RequestBody con carga de archivos ¿es posible?



upload file spring mvc (5)

Agregue el siguiente bean en su spring-servlet.xml para agregar el soporte para la solicitud de varias partes.

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />

Tampoco olvides agregar la dependencia para el archivo commons-fileupload jar.

Tengo un controlador como este y quiero enviar un formulario con la carga de archivos, así como algunos datos de formularios como la etiqueta, como se muestra a continuación. Además, quiero hacer eso usando @RequestBody para poder usar la anotación @Valid en el contenedor, ya que se agregarán más variables.

public @ResponseBody WebResponse<Boolean> updateEUSettings( final Locale locale, @Validated @ModelAttribute final EUPSettingsWrapper endUserPortalSettingsWrapper) { }

Y mi envoltorio es:

public class EUPSettingsWrapper { private String label; private MultipartFile logo; // getter , setters..etc... }

Pero me gustaría convertirlo en un @RequestBody de ModelAttributes.

La forma en que lo estoy intentando es tener la carga del archivo separada como un parámetro de solicitud como este:

public @ResponseBody WebResponse<Boolean> updateEUSettings( final Locale locale, @Validated @RequestBody final EUPSettingsWrapper endUserPortalSettingsWrapper, @RequestParam(value = "file1", required = true) final MultipartFile logo) { endUserPortalSettingsWrapper.setLogo(logo); // ... }

En mi simulacro MVC, estoy configurando:

getMockMvc().perform(fileUpload(uri).file(logo) .accept(MediaType.APPLICATION_JSON) .content(JSONUtils.toJSON(wrapper)) .contentType(MediaType.MULTIPART_FORM_DATA)) .andExpect(status().isOk());

Pero estoy recibiendo un error como este que dice:

org.springframework.web.HttpMediaTypeNotSupportedException: Content type ''multipart/form-data'' not supported

¿Alguien tiene una buena idea de cómo se pueden usar las cargas de archivos de varias partes con @RequestBody? ¿Algo que estoy haciendo mal arriba?


Luché un poco con esto y terminé pasando por parámetros simples. Bien si no tienes mucho que pasar en tu solicitud:

myMethod(@RequestParam("file") MultipartFile myFile, @RequestParam("param1") Float param1, @RequestParam("param2") String param2 {}


No pude encontrar una manera de usar @RequestBody.

Sin embargo, puedes hacer algo como esto:

@RequestMapping(value = "/uploadStuff", method = RequestMethod.POST) public MyViewDto doStuff(@RequestPart("json") @Valid MyDto dto, @RequestPart("file") MultipartFile file) { ... }

Puedes probarlo así:

MockMultipartFile jsonFile = new MockMultipartFile("json", "", "application/json", "{}".getBytes()); MockMultipartFile dataFile = new MockMultipartFile("file", "foo.zip", "application/octet-stream", bytes); mockMvc.perform(fileUpload("/uploadStuff") .file(dataFile) .file(jsonFile)) .andExpect(status().isOk());


Para Spring 4 y versiones posteriores, puede hacer lo siguiente para obtener el objeto completo:

public ResponseEntity<Object> upload(@Payload EUPSettingsWrapper wrapper) { }

Nota: También debería funcionar sin la etiqueta.

public ResponseEntity<Object> upload(EUPSettingsWrapper wrapper) { }


Puede simplificar su vida aquí, ya que todo lo que está haciendo es enviar un formulario que contiene algunos campos y archivos. No necesitas @RequestBody para lo que estás tratando de hacer. Puede usar las funciones regulares de Spring MVC, por lo que su método de control sería:

@ResponseBody public WebResponse<Boolean> updateEUSettings( Locale locale, @Valid EUPSettingsWrapper endUserPortalSettingsWrapper, @RequestParam(value = "file1", required = true) MultipartFile logo ) { }

El cliente que envíe la solicitud a este controlador deberá tener un formulario con enctype="multipart/form-data" .

En tu prueba Spring MVC escribirías algo como esto:

getMockMvc().perform(fileUpload(uri).file("file1", "some-content".getBytes()) .param("someEuSettingsProperty", "someValue") .param("someOtherEuSettingsProperty", "someOtherValue") .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.MULTIPART_FORM_DATA)) .andExpect(status().isOk());