当前位置:   article > 正文

通过RestTemplate调用参数为MultipartFile的接口上传文件 + 踩坑_resttemplate上传multipartfile

resttemplate上传multipartfile

调用接口定义

    @ResponseBody
    @RequestMapping(value = "/upload",consumes = "multipart/form-data")
    public CustomUploadResult uploadFile(@RequestParam(value = "file") MultipartFile file,
                           				 @RequestParam(value = "fileName") String fileName) throws Exception {
        //逻辑处理
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

调用

    /**
     * 接受到byte[]文件数据后,调用上述的upload接口上传文件
     * @param fileData 文件数据
     * @param fileName 文件名
     */
    void upload(byte[] fileData, String fileName) {
        //请求头,以表单形式提交
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
        headers.add("Content-Type", MediaType.MULTIPART_FORM_DATA_VALUE);

        //请求传参
        ByteArrayResource fileAsResource = new ByteArrayResource(fileData){
            @Override
            public String getFilename() {
                return fileName;
            }

            @Override
            public long contentLength() {
                return fileData.length;
            }
        };
        MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
        param.add("file", fileAsResource);
        param.add("fileName", "测试.docx");

        //构建uri
        URI uri = new URI("https://接口地址/upload");
        //传参
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(param, headers);
        //调用接口
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<CustomUploadResult> responseEntity = restTemplate.exchange(
                uri, HttpMethod.POST, requestEntity,
                new ParameterizedTypeReference<CustomUploadResult>() {});
        log.info("调用接口结束,回参:{}", JSON.toJSONString(responseEntity));
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

需要重写getFilename、contentLength的原因:上传文件时RestTemplate会通过相应方法得到文件流的大小、文件名
参考博客:http://events.jianshu.io/p/93616d280e29

除ByteArrayResource外,还可使用InputStreamResource、FileSystemResource。
不过FileSystemResource需要传递一个文件,可用于上传本地文件。如果是接收到文件流再上传的情况,使用FileSystemResource的话,需要先将文件流转为文件临时存储在本地,再读取本地文件上传,上传之后还需要删除本地临时文件,麻烦且消耗资源。

通过FileSystemResource上传文件并通过fastjson打印传参踩坑

问题描述:使用FileSystemResource读取文件发送给上传接口时,接口能接收到文件对象,但是长度为0且文件内容被清空
上传前文件内容:
在这里插入图片描述
上传后文件内容:
在这里插入图片描述
代码:

    /**
     * 通过FileSystemResource上传本地文件
     */
    void upload() {
        //请求头,以表单形式提交
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
        headers.add("Content-Type", MediaType.MULTIPART_FORM_DATA_VALUE);

        //请求传参
        File file = new File("C:\\文件路径\\测试.docx");
        FileSystemResource resource = new FileSystemResource(file);
        MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
        param.add("file", resource);
        param.add("fileName", "测试.docx");

        //构建uri
        URI uri = new URI("接口地址");
        //传参
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(param, headers);
        //调用接口
        RestTemplate restTemplate = new RestTemplate();
        //!!!!!!!导致出问题的代码!!!!!!!!!!!!
        log.info("调用接口开始,传参:{}", JSON.toJSONString(requestEntity));
        ResponseEntity<CustomUploadResult> responseEntity = restTemplate.exchange(
                uri, HttpMethod.POST, requestEntity,
                new ParameterizedTypeReference<CustomUploadResult>() {});
        log.info("调用接口结束,回参:{}", JSON.toJSONString(responseEntity));
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

问题原因:
在这里插入图片描述
参考:https://github.com/alibaba/fastjson/issues/3547

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号