RestTemplate上传文件的相关基础和技巧

背景

最近在做持续集成&持续交付,程序需要自动下载文件,并自动上传交付到其他接口。

步骤

  1. 使用API下载文件。
  2. 创建临时文件。
  3. 转发文件,并交付到其他系统。

这里有两个技巧

  1. 怎么使用临时文件的同时,也用我们指定的文件名来上传。
  2. RestTemplate上传文件时,execute没有地方传Headers,如何传认证信息。

下载文件

这里需要考虑的是直接写入到磁盘,避免大文件带来内存问题。

      RestTemplate restTemplate = new RestTemplate();
      File file = null;
      try {
          ArrayList<ClientHttpRequestInterceptor> inter = new ArrayList<>();
          inter.add((request, body, execution) -> {
              request.getHeaders().set(HttpHeaders.AUTHORIZATION, "Bearer " + "技巧一:用RestTemplate.execute方法时,传递HTTP Token");
              return execution.execute(request, body);
          });
          restTemplate.setInterceptors(inter);//不需要认证的,可以去掉拦截器。
          file = restTemplate.execute(fileUrl, HttpMethod.GET, null, clientHttpResponse -> {
              File ret = File.createTempFile("cicd-", fileName); //创建文件临时文件,文件名不确定,中间有随机数值,不用担心重复
              StreamUtils.copy(clientHttpResponse.getBody(), new FileOutputStream(ret)); //这个是org.springframework.util.StreamUtils,他有Buffer,不会占用过大内存。
              logger.info("created temp file {}", ret.getAbsolutePath());
              return ret;
          });
      }catch (Exception e) {
          logger.error("download failed, check url: {}", fileUrl, e);
      }

转发文件


        FileSystemResource fileSystemResource = new FileSystemResource(file){
            @Override
            public String getFilename() {
                return StringUtils.defaultString(deliverySettingsItem.getFileName(), super.getFilename()); //技巧二,设置文件名,这里可以代替temp文件名
            }
        };

        MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
        form.add("file", fileSystemResource); //这里file是取决于 接收端取文件的字段定义是什么。

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

        HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<>(form, headers);

        String filePath = null;
        try {
            restTemplate.postForObject(FILE_API, files, String.class); //这里根据实际返回的结果来设置返回类型。
        } catch (Exception e) {
            logger.error("投递文件失败", e);
            throw e;
        }

//接收端
public void uploadLocalFile(@RequestParam("file") MultipartFile file) {
    logger.info("上传文件名{}", file.getOriginalFilename());
    //.....
}

注册文件

有些系统上传文件一步到位,有些分两步,第一步上传文件得到一个PATH,然后第二步需要纯注册文件。
具体就和正常调用接口是一样的。

posted @ 2020-09-28 17:43  一杯半盏  阅读(1128)  评论(0编辑  收藏  举报