2014-05-08 15 views
16

Ich habe einen Controller wie folgt und ich möchte ein Formular mit Dateiupload sowie einige Formulardaten wie Etikett wie unten gezeigt senden. Ich möchte das auch mit @RequestBody tun, damit ich die @Valid Annotation auf dem Wrapper verwenden kann, da mehr Variablen hinzugefügt werden.Spring Controller @RequestBody mit Datei-Upload ist es möglich?

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

und meine Wrapper ist

public class EUPSettingsWrapper { 

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

, aber ich würde es in von ModelAttrbutes zu einem @RequestBody konvertieren möchten.

die Art, wie ich versucht habe ist, indem Sie die Datei-Upload als Anfrageparameter wie diese

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

    endUserPortalSettingsWrapper.setLogo(logo); 

    // ... 
} 

in meinem Mock mvc getrennt mit i

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

setze aber ich erhalte eine Fehlermeldung wie diese was sagt

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

Jeder hat eine gute Idee, wie Multipart Dateiuploads wi verwendet werden können th @RequestBody. Was mache ich oben falsch?

Antwort

22

Sie tatsächlich Ihr Leben vereinfachen hier hinzuzufügen, da alles, was Sie tun, ist ein Formular abgeschickt werden, dass einige Felder und Datei enthält. Sie nicht benötigen @RequestBody für das, was Sie versuchen zu tun. Sie können reguläre Spring MVC-Funktionen verwenden, so dass Ihr Controller-Methode wie folgt aussehen würde:

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


} 

Der Client, ein Formular mit enctype="multipart/form-data" haben müssen die Anforderung an diesen Controller sendet.

In Ihrem Spring MVC-Test würden Sie so etwas schreiben:

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

Fügen Sie die folgende Bean in Ihrer spring-servlet.xml hinzu, um die Unterstützung für eine mehrteilige Anfrage hinzuzufügen.

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

Vergessen Sie auch nicht die Abhängigkeit für commons-Fileupload Glas kann

+0

danke gespeichert viel Aufwand .. – pratikabu

3

ich nicht einen Weg @RequestBody zu benutzen finden.

Allerdings können Sie etwas tun:

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

Sie können es wie folgt testen:

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

kämpfte ich ein wenig mit diesem und endete als einfachen Parameter. Gut, wenn Sie nicht viel in Ihrer Anfrage zu übergeben haben:

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