2014-05-08 16 views
16

Ho un controller come questo e voglio inviare un modulo con il caricamento del file così come alcuni dati come l'etichetta come mostrato di seguito. Anche io voglio farlo in bu usando @RequestBody in modo che io possa usare l'annotazione @Valid sul wrapper dato che verranno aggiunte più variabili.Spring Controller @RequestBody con upload di file è possibile?

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

e la mia fascia è

public class EUPSettingsWrapper { 

    private String label; 
    private MultipartFile logo; 
// getter , setters..etc... 
} 

ma vorrei convertirlo in un @RequestBody da ModelAttrbutes.

il modo in cui sto provando è di avere il caricamento di file separato come parametro di richiesta come questo

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

    endUserPortalSettingsWrapper.setLogo(logo); 

    // ... 
} 

nel mio MVC finto io pongo

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

ma sto ottenendo un errore come questo che dice

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

qualcuno ha una buona idea di come possono essere utilizzati i caricamenti di file Multipart th @RequestBody. Qualcosa che sto facendo male sopra?

risposta

22

Si può effettivamente semplificare la vita qui dal momento che tutti si stanno facendo è la presentazione di una forma che contiene alcuni campi e file. È non necessario @RequestBody per ciò che si sta tentando di fare. È possibile utilizzare normali funzioni di Spring MVC, in modo che il metodo di controllo sarà simile:

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


} 

Il client che invia la richiesta a questo controller sarà necessario avere un modulo con enctype="multipart/form-data".

Nel tuo test Spring MVC si potrebbe scrivere qualcosa di simile:

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()); 
8

Si prega di aggiungere il seguente bean in spring-servlet.xml per aggiungere il supporto per la richiesta multipart.

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

Inoltre, non dimenticare di aggiungere la dipendenza per vaso commons-fileupload

+0

grazie salvato un sacco di sforzi .. – pratikabu

3

non riuscivo a trovare un modo per utilizzare @RequestBody.

Tuttavia, si può fare qualcosa di simile:

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

È possibile verificare in questo modo:

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()); 
0

ho faticato un po 'con questo e ha finito per il passaggio di parametri come semplici. Bene, se non hai molto da passare nella tua richiesta:

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