使用RestTemplate的CommonsMultipartFile的文件上传失败 [英] File upload of CommonsMultipartFile using RestTemplate is failing

查看:568
本文介绍了使用RestTemplate的CommonsMultipartFile的文件上传失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用在请求中接受CommonsMultipartFile的Web服务.因此,我使用Spring的RestTemplate创建了一个HTTP客户端.下面是将URI和MultipartFile作为参数的方法.我正在尝试将此文件以ByteArrayResource的形式传递给Web服务.

I'm trying to consume a web service that accepts a CommonsMultipartFile in the request. So, I created an HTTP client using Spring's RestTemplate. Below is the method that takes in URI and a MultipartFile as parameters. I'm trying to pass this file to the web service in the form of ByteArrayResource.

public String upload(String uri, MultipartFile file) throws IOException {
    logger.info("URI: " + uri);

    ByteArrayResource fileAsResource = new ByteArrayResource(file.getBytes()) {
        @Override
        public String getFilename() {
            return file.getOriginalFilename();
        }
    };

    MultiValueMap<String, Object> parts = new LinkedMultiValueMap<String, Object>();
    parts.add("file", fileAsResource);
    parts.add("fileName", file.getOriginalFilename());

    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);

    HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String, Object>>(parts, httpHeaders);

    ResponseEntity<String> responseEntity = rest.exchange(uri, HttpMethod.POST, requestEntity, String.class);

    this.setStatus(responseEntity.getStatusCode());
    return responseEntity.getBody();
}

这是我创建CommonsMultipartFile的方式:

This is how I'm creating a CommonsMultipartFile:

private MultipartFile getCommonsMultipartFile() throws FileNotFoundException, IOException {
    File file = new File("C:\\Dummy_Test.txt");

    DiskFileItemFactory factory = new DiskFileItemFactory();
    FileItem fileItem = factory.createItem( "file", "multipart/form-data", false, "Dummy_Test.txt" );
    IOUtils.copy(new FileInputStream(file), fileItem.getOutputStream());
    MultipartFile commonsMultipartFile = new CommonsMultipartFile(fileItem);

    return commonsMultipartFile;
}

但是,每当我运行此客户端以访问Web服务时,我都会不断收到此错误.

But whenever I run this client to hit the web service I keep getting this error.

 org.springframework.web.client.ResourceAccessException: I/O error: resource loaded from byte array cannot be resolved to absolute file path; nested exception is java.io.FileNotFoundException: resource loaded from byte array cannot be resolved to absolute file path
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:453)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:401)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:377)
    at com.attikala.service.UploaderService.upload(UploaderService.java:118)
    at com.attikala.service.UploaderService.main(UploaderService.java:55)
Caused by: java.io.FileNotFoundException: resource loaded from byte array cannot be resolved to absolute file path
    at org.springframework.core.io.AbstractResource.getFile(AbstractResource.java:107)
    at org.springframework.core.io.AbstractResource.contentLength(AbstractResource.java:116)
    at org.springframework.http.converter.ResourceHttpMessageConverter.getContentLength(ResourceHttpMessageConverter.java:99)
    at org.springframework.http.converter.ResourceHttpMessageConverter.write(ResourceHttpMessageConverter.java:81)
    at org.springframework.http.converter.ResourceHttpMessageConverter.write(ResourceHttpMessageConverter.java:1)
    at org.springframework.http.converter.FormHttpMessageConverter.writePart(FormHttpMessageConverter.java:288)
    at org.springframework.http.converter.FormHttpMessageConverter.writeParts(FormHttpMessageConverter.java:252)
    at org.springframework.http.converter.FormHttpMessageConverter.writeMultipart(FormHttpMessageConverter.java:242)
    at org.springframework.http.converter.FormHttpMessageConverter.write(FormHttpMessageConverter.java:194)
    at org.springframework.http.converter.FormHttpMessageConverter.write(FormHttpMessageConverter.java:1)
    at org.springframework.web.client.RestTemplate$HttpEntityRequestCallback.doWithRequest(RestTemplate.java:588)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:436)
    ... 4 more

有人可以帮我弄清楚这里发生了什么吗?

Can someone help me in figuring out what's happening here?

注意:如果我使用以下代码上传文件,则可以正常运行.

Note: If I use the below code to upload the file, it works perfectly fine.

public String upload(String uri) {
    LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>();

    FileSystemResource value = new FileSystemResource(new File("C:\\Dummy_Test.txt"));
    map.add("file", value);
    map.add("fileName", "Dummy_Test.txt");

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);

    HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<>(map, headers);

    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<String> responseEntity = restTemplate.exchange(uri, HttpMethod.POST, requestEntity, String.class);

    return responseEntity.getBody();
}

所以,我在想,我是否需要始终为要上传的文件提供绝对路径?我知道我在这里想念什么.不知道什么.

So, I'm thinking, do I need to provide absolute path always for the file I'm uploading? I know I'm missing something here. Don't know what.

谢谢.

推荐答案

最后,我发现了正在发生的事情. 我走了-

Finally, I found what's happening. Here I go -

此声明时

ResponseEntity<String> responseEntity = rest.exchange(uri, HttpMethod.POST, requestEntity, String.class);

被执行,它试图在幕后从传递的MultipartFile中提取类型为java.io.File的文件,然后获取文件长度.但是MultipartFile不是这种类型,因此它引发了异常.

gets executed, behind the scenes it's trying to extract the file of type java.io.File from the MultipartFile passed, and then get the file length. But MultipartFile is not of that type and as a result it was throwing an exception.

要解决的问题是,在创建ByteArrayResource的实例时,我还必须重写contentLength()方法. -

To fix that I had to also override contentLength() method when creating an instance of ByteArrayResource. Ta-da!

    ByteArrayResource fileAsResource = new ByteArrayResource(file.getBytes()) {

        @Override
        public String getFilename() {
            return file.getOriginalFilename();
        }

        @Override
        public long contentLength() throws IOException {
            return file.getSize();
        }
    };

希望这对任何遇到相同问题的人都有帮助.

Hope this helps if anyone runs into the same problem.

这篇关于使用RestTemplate的CommonsMultipartFile的文件上传失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆