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 @   一杯半盏  阅读(1149)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示