欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

RestTemplate上传多文件异常解决

程序员文章站 2022-10-03 13:32:43
RestTemplate上传文件方法都知道前端往后端传文件是通过form的形式,后端web程序之间上传,也是通过form表单。使用MultiValueMap类。MultiValueMap formData = new LinkedMultiValueMap<>();ByteArrayResource fileAsResource = new ByteArrayResource(a.getBytes()){ @Override public String getFilenam...

RestTemplate上传文件方法

都知道前端往后端传文件是通过form的形式,后端web程序之间上传,也是通过form表单。使用MultiValueMap类。

MultiValueMap formData = new LinkedMultiValueMap<>();
ByteArrayResource fileAsResource = new ByteArrayResource(a.getBytes()){
    @Override
    public String getFilename() {
        return a.getOriginalFilename();
    }

    @Override
    public long contentLength() {
        return a.getSize();
    }
};
formData.add("file",fileAsResource);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity request = new HttpEntity<>(map,headers);
ResponseEntity<Object> response = restTemplate.postForEntity(url,request,Object.class);

上传多文件所遇问题

这边我需要上传多个文件,在前端传过来时,我的接口是直接用List来接收的。于是我想当然的直接将MultiPartFile列表转化成了ByteArrayResource的list。
RestTemplate上传多文件异常解决
通过这种方式上传文件之后,在消息转化器处报错了。错误描述说是不能转换ByteArrayInputStream。
RestTemplate上传多文件异常解决

问题分析

上面说到消息转换器报错,于是查看我们使用的类,ByteArrayResource。继承自AbstractResource。RestTemplate上传多文件异常解决
再看AbstractResource继承自Resource类。RestTemplate上传多文件异常解决
那么这个Resource的子类,是可以被ResourceHttpMessageConverter解析转换的。开始Debug RestTemplate请求流程。每个HttpMessageConverter都有自己的支持的转换类型。通过查看canRead方法,或者supports方法可以查看支持的转换类型。
RestTemplate上传多文件异常解决
debug RestTemplate处理流程,发现该次请求,使用了AllEncompassingFormHttpMessageConverter,因为我们传输的数据类型是MultiValueMap。这个转换器没有什么方法,大部分直接继承FormHttpMessageConverter,而FormHttpMessageConverter是支持Resource对象转换的,按道理来说应该是可以转换的。RestTemplate上传多文件异常解决
继续debug,发现在写转换的时候,使用了MappingJackson2HttpMessageConverter,而没有使用ResourceHttpMessageConverter。在writePart方法中,发现转换的对象类型是List,所以调用了支持Object类型转换的Mapping转换器。RestTemplate上传多文件异常解决
RestTemplate上传多文件异常解决
报错原因找到了,尝试改为add文件数组,看了一下form里面的对象类型,是Object,肯定不行,跑完果然还是报错。
RestTemplate上传多文件异常解决
由于通过debug发现,是由于我们传输的对象类型错误,才导致HttpMessageConverter出错,接下来聚焦到对象传输上。查看MultiValueMap的add方法,看到这个add方法,一下就找到了问题所在,它会获取当前Key的LinkedList。然后将对象add到这个list里面。那么我们传递list显然是不科学的。
RestTemplate上传多文件异常解决
改为循环add ByteArrayResource,再查看MultiValueMap,已经不是Object了,而是我们的匿名内部类。
RestTemplate上传多文件异常解决
再debug到FormHttpMessageConverter中,此时转换这个files所用的转换器,终于是ResourceHttpMessageConverter了,继续运行,果然就可以了,问题解决。
RestTemplate上传多文件异常解决

问题总结

1、RestTemplate上传多文件时,一定要循环add Resource。
2、要重写getFileName方法和contentLength方法。

本文地址:https://blog.csdn.net/weixin_43838174/article/details/109568891

相关标签: java