使用 Spring 4 restTemplate(Java 客户端和 RestController)上传 MultipartFile 列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42212557/
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-11-03 06:27:35  来源:igfitidea点击:

Uploading a List of MultipartFile with Spring 4 restTemplate (Java Client & RestController)

javaspringspring-mvcmultipartform-dataresttemplate

提问by Steve

I am trying to post of List of MultipartFile to my RestController using spring restTemplate although I'm a bit confused as to the exact syntax & types to use for my client & controller. Here's what I have so far based on the research I've done...

我正在尝试使用 spring restTemplate 将 MultipartFile 列表发布到我的 RestController,尽管我对用于我的客户端和控制器的确切语法和类型有些困惑。这是我迄今为止根据我所做的研究所做的......

FileUploadClient.java

文件上传客户端.java

public void uploadFiles(List<MultipartFile> multiPartFileList) throws IOException {
    MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
    List<Object> files = new ArrayList<>();
    for(MultipartFile file : multiPartFileList) {
        files.add(new ByteArrayResource(file.getBytes()));
    }
    map.put("files", files);

    // headers is inherited from BaseClient
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);
    HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(map, headers);
    ResponseEntity<String> response = restTemplate.exchange(restURI + "/rest/fileupload/uploadfiles", HttpMethod.POST, request, String.class);
    if(HttpStatus.OK.equals(response.getStatusCode())) {
        System.out.println("status for /rest/fileupload/uploadfiles ---> " + response);
    }
}

FileUploadRestController.java

文件上传RestController.java

@RequestMapping(value = "/uploadfiles", method = RequestMethod.POST)
public ResponseEntity<?> uploadFiles(@RequestParam("files") List<MultipartFile> files, HttpServletRequest request) {
    ResponseEntity<?> response;
    try {
        // do stuff...
        response = new ResponseEntity<>(header, HttpStatus.OK);
        System.out.println("file uploaded");
    } catch (Exception e) {
        // handle exception
    }
    return response;
}

web.xml

网页.xml

<filter>
    <filter-name>multipartFilter</filter-name>
    <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>multipartFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

spring-servlet.xml

spring-servlet.xml

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- max upload size in bytes -->
    <property name="maxUploadSize" value="20971520" /> <!-- 20MB -->
    <!-- max size of file in memory (in bytes) -->
    <property name="maxInMemorySize" value="1048576" /> <!-- 1MB -->
</bean>

If I understand it correctly. The multipart filter should parse my MultiValueMap into a List of MultipartFiles and a MultipartHttpServletRequest? The only way I can get my client to hit my RestController is to send the file data as a ByteArrayResource, however in my Controller my RequestBody is always null and the MultipartHttpServletRequest has an empty map for its multipartFiles attribute. I've looked at numerous posts to try to resolve this issue but to no avail. Any help would be much appreciated.

如果我理解正确的话。多部分过滤器应该将我的 MultiValueMap 解析为 MultipartFiles 列表和 MultipartHttpServletRequest?让我的客户端访问我的 RestController 的唯一方法是将文件数据作为 ByteArrayResource 发送,但是在我的控制器中,我的 RequestBody 始终为空,并且 MultipartHttpServletRequest 的 multipartFiles 属性有一个空映射。我查看了许多帖子以尝试解决此问题,但无济于事。任何帮助将非常感激。

回答by Darshan Mehta

It looks like the requestpayload that you are sending from FileUploadClientdoes not match what's server is expecting. Could you try changing the following:

看起来request您发送的有效负载FileUploadClient与服务器期望的不匹配。您可以尝试更改以下内容:

MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
for(MultipartFile file : multiPartFileList) {
    map.add(file.getName(), new ByteArrayResource(file.getBytes()));
}

to

MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
List<ByteArrayResource> files = new ArrayList<>();
for(MultipartFile file : multiPartFileList) {
    files.add(new ByteArrayResource(file.getBytes()));
}
map.put("files", files);

Also, could you try changing the server's method signature to the following:

另外,您能否尝试将服务器的方法签名更改为以下内容:

public ResponseEntity<?> uploadFiles(@RequestParam("files") List<MultipartFile> files, HttpServletRequest request) {

Update

更新

While uploading multiple files, you need to make sure getFileNameof ByteArrayResourcereturns same value every time. If not, you will always get an empty array.

同时上传多个文件,你需要确保getFileNameByteArrayResource每次都返回相同的值。如果没有,您将始终得到一个空数组。

E.g. the following works for me:

例如以下对我有用:

Client:

客户:

MultiValueMap<String, Object> data = new LinkedMultiValueMap<String, Object>(); 
for(MultipartFile file : multiPartFileList) { 
    ByteArrayResource resource = new ByteArrayResource(file.getBytes()) { 
        @Override 
        public String getFilename() { 
            return ""; 
        } 
    }; 
    data.add("files", resource);
} 

Server

服务器

public ResponseEntity<?> upload(@RequestParam("files") MultipartFile[] files){