RestTemplate上传文件

RestTemplate上传文件其实是一个非常简单的操作,这次之所以踩坑一方面是自己给自己挖的,一方面是接口提供方给我挖的。

我给自己挖的坑是我在配置RestTemplate时,清除了所有默认的HttpMessageConverter,然后只设置了一个FastJsonHttpMessageConverter,结果针对上传操作,这个HttpMesageConverter无法进行转换,就报了一个错出来。不过还好,因为RestTemplate是我自己配置的,所以我很快就定位了这个问题,最后将配置代码中清理HttpMessageConverter的代码清除了(又踩了一次,所以加重该笔记)。

第二个问题是接口提供方的编码中应该写死要求上传时的文件名为file,而用RestTemplate上传时准备的MultiValueMap太具备迷惑性,到时我一直以为该参数的key就是上传时的文件名,所以用这种写法时接口一直报500。最后找到了一篇博文,抱着试一试的想法,尝试了一下,解决了我的问题(实际上我去接口提的后台查看了接口报错,猜到了其写法)。

我最终的代码如下:

 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

public String uploadPictureBytes(byte[] bytes) {

    // 计算md5值,作为文件名
    String fileName = md5_32Encrypt(bytes);

    // 设置请求体
    MultiValueMap<String, Object> bodyParams = new LinkedMultiValueMap<>();
    bodyParams.add("file", new ByteArrayResource(bytes) {
        @Override
        public String getFilename() {
            return "file";
        }
    });

    // 设置请求头
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);

    // 封装整个报文
    HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(bodyParams, headers);

    // 发送请求
    ResponseForUpload response = restTemplate.postForObject(
            String.format(URL_FOR_UPLOAD, fileName),
            requestEntity, ResponseForUpload.class);

    // 处理返回结果
    if (response != null && response.getCode() == 200) {
        return response.getData().getPath();
    }

    throw new BusinessException(PICTURE_UPLOAD_WRONG);
}

参考资料

  1. spring restTemplate 上传文件流