Spring Controller @RequestBody 可以上传文件吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23533355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 06:42:56  来源:igfitidea点击:

Spring Controller @RequestBody with file upload is it possible?

springspring-mvcmultipartmultipartform-data

提问by Yatin

I have a Controller like this and I want to submit a form with file uploading as well as some form data like label as shown below. Also, I want to do that using @RequestBody so I can use the @Valid annotation on the wrapper as more variables will be added.

我有一个这样的控制器,我想提交一个带有文件上传的表单以及一些表单数据,如标签,如下所示。另外,我想使用 @RequestBody 来做到这一点,这样我就可以在包装器上使用 @Valid 注释,因为将添加更多变量。

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

And my wrapper is:

我的包装是:

public class EUPSettingsWrapper {

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

But I would like to convert it into a @RequestBody from ModelAttributes.

但我想将它从 ModelAttributes 转换为 @RequestBody。

The way I'm trying is by having the file upload separated as request parameter like this:

我尝试的方法是将文件上传作为请求参数分开,如下所示:

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 my mock MVC, I am setting:

在我的模拟 MVC 中,我设置:

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

But I'm getting an error like this which says:

但我收到这样的错误,其中说:

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

Does anyone have a good idea of how Multipart file uploads can be used with @RequestBody? Anything I am doing wrong above?

有没有人知道如何将多部分文件上传与@RequestBody 一起使用?我在上面做错了什么吗?

回答by geoand

You can actually simplify your life here since all you are doing is submitting a form that contains some fields and file. You don'tneed @RequestBody for what you are trying to do. You can use regular Spring MVC features, so your controller method would look like:

您实际上可以在这里简化您的生活,因为您所做的只是提交一个包含一些字段和文件的表单。你并不需要为你正在尝试做@RequestBody。您可以使用常规的 Spring MVC 功能,因此您的控制器方法将如下所示:

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


}

The client that submits the request to this controller will need to have a form with enctype="multipart/form-data".

向该控制器提交请求的客户端需要有一个带有enctype="multipart/form-data".

In your Spring MVC test you would write something like this:

在您的 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());

回答by Ankur Jain

Please add the following bean in your spring-servlet.xml to add the support for multipart request.

请在 spring-servlet.xml 中添加以下 bean 以添加对多部分请求的支持。

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

Also don't forget to add the dependency for commons-fileupload jar

另外不要忘记为commons-fileupload jar添加依赖项

回答by hookumsnivy

I couldn't find a way to use @RequestBody.

我找不到使用@RequestBody 的方法。

However, you can do something like this:

但是,您可以执行以下操作:

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

You can test it like this:

你可以这样测试:

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

回答by Jason Glez

For Spring 4 and later you can do the following to get the full object:

对于 Spring 4 及更高版本,您可以执行以下操作来获取完整对象:

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

}

Note: Also should work without the tag

注意:也应该在没有标签的情况下工作

public ResponseEntity<Object> upload(EUPSettingsWrapper wrapper) {

}

回答by Andy B

I struggled a little with this and ended up passing as simple parameters. Fine if you don't have lots to pass in your request:

我对此有点挣扎,最终以简单的参数形式传递。如果您的请求中没有很多要传递的内容,那很好:

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