web-dev-qa-db-ja.com

Spring Controller @RequestBodyとファイルのアップロードは可能ですか?

このようなコントローラーがあり、ファイルをアップロードするフォームと、以下に示すラベルなどのフォームデータを送信したいです。また、@ RequestBodyを使用してこれを行いたいので、変数が追加されるときにラッパーで@Validアノテーションを使用できます。

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

そして私のラッパーは:

public class EUPSettingsWrapper {

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

しかし、ModelAttributesから@RequestBodyに変換したいと思います。

私がしようとしている方法は、次のようにリクエストパラメータとしてファイルアップロードを分離することです:

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

    endUserPortalSettingsWrapper.setLogo(logo);

    // ...
}

私のモックMVCでは、以下を設定しています:

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

しかし、次のようなエラーが表示されます。

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

マルチパートファイルアップロードを@RequestBodyで使用する方法について、だれかがよく知っていますか?上記で私が間違っていることは何ですか?

30
Yatin

ここでは、いくつかのフィールドとファイルを含むフォームを送信するだけなので、実際にここでの生活を簡素化できます。あなたdo n'tあなたがしようとしていることのために@RequestBodyが必要です。通常のSpring MVC機能を使用できるため、コントローラーメソッドは次のようになります。

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


}

このコントローラーにリクエストを送信するクライアントは、enctype="multipart/form-data"

Spring MVCテストでは、次のように記述します。

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());
36
geoand

Spring-servlet.xmlに次のBeanを追加して、マルチパートリクエストのサポートを追加してください。

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

commons-fileupload jarの依存関係を追加することも忘れないでください

11
Ankur Jain

@RequestBodyを使用する方法が見つかりませんでした。

ただし、次のようなことができます。

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

次のようにテストできます。

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());
5
hookumsnivy

Spring 4以降では、以下を実行して完全なオブジェクトを取得できます。

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

}

注:タグなしでも動作するはずです

public ResponseEntity<Object> upload(EUPSettingsWrapper wrapper) {

}
0
Jason Glez