使用RestTemplate|使用RestTemplate 调用远程接口上传文件方式

目录

  • RestTemplate 调用远程接口上传文件
    • 问题描述
    • 解决方法
      • 第一种方式
      • 第二种方式
  • RestTemplate调用远程接口添加请求头

    RestTemplate 调用远程接口上传文件
    问题描述
    【使用RestTemplate|使用RestTemplate 调用远程接口上传文件方式】第三方写了一个文件上传的接口,该接口的请求方式为Post请求,请求参数全部是以form-data表单形式进行提交,包含三个参数
    • 第一个:cookie(字符串类型)
    • 第二个:seqNo(字符串类型)
    • 第三个:file(文件类型)

    解决方法
    使用传统的Spring Cloud的Feign组件在调用远程接口实现文件上传时有时会出现异常错误,可考虑使用下述两种方式文件上传

    第一种方式 使用RestTemplate进行调用
    import org.springframework.core.io.InputStreamResource; import java.io.InputStream; public class CommonInputStreamResource extends InputStreamResource {private long length; private String fileName; public CommonInputStreamResource(InputStream inputStream, long length, String fileName) {super(inputStream); this.length = length; this.fileName = fileName; } /*** 覆写父类方法* 如果不重写这个方法,并且文件有一定大小,那么服务端会出现异常* {@code The multi-part request contained parameter data (excluding uploaded files) that exceeded}*/@Overridepublic String getFilename() {return fileName; } /*** 覆写父类 contentLength 方法* 因为 {@link org.springframework.core.io.AbstractResource#contentLength()}方法会重新读取一遍文件,* 而上传文件时,restTemplate 会通过这个方法获取大小。然后当真正需要读取内容的时候,发现已经读完,会报如下错误。*/@Overridepublic long contentLength() {long estimate = length; return estimate == 0 ? 1 : estimate; } public void setLength(long length) {this.length = length; } public void setFileName(String fileName) {this.fileName = fileName; }}

    try{String applySeqNo = "123456"; String cookie="654321"; File file=new File("E:\\1.rar"); FileInputStream fileInputStream=new FileInputStream(file); //请求头设置为MediaType.MULTIPART_FORM_DATA类型HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); //构建请求体MultiValueMap requestBody = new LinkedMultiValueMap<>(); CommonInputStreamResource commonInputStreamResource = null; try {commonInputStreamResource = new CommonInputStreamResource(fileInputStream,file.length(),file.getName()); } catch (Exception e) { log.error("文件输入流转换错误",e); }requestBody.add("cookie", cookie); requestBody.add("seqNoFile", applySeqNo); requestBody.add("file",commonInputStreamResource); HttpEntity requestEntity = new HttpEntity(requestBody, requestHeaders); //直接调用远程接口ResponseEntity responseEntity = restTemplate.postForEntity("http://xxx.xxx.xxx.xxx:8080/test/upload",requestEntity, String.class); System.out.println("返回结果:"+responseEntity.getBody())}catch (Exception e){log.error("远程调用出现异常:", e); }


    第二种方式 Spring Cloud Feign组件 + MultiValueMap + CommonInputStreamResource
    CommonInputStreamResource对象的构造在上面已经实现了这里就不再重复构造,沿用上面的那个就行
    feign接口
    @Component@FeignClient(name = "taxRecodes", url = "${spider.url}", qualifier = "TaxRecodeFeignClient",fallback = TaxRecodeFallBack.class)public interface TaxRecodeFeignClient {/*** 单证申请-合同信息表附件上传*/@PostMapping(value = "https://www.it610.com/attachFile/upload",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)String attachFileUpload(MultiValueMap multiValueMap); }

    请求部分
    @PostMapping("/upload")public void upload(){try {File file=new File("E:\\1.rar"); FileInputStream fileInputStream=new FileInputStream(file); CommonInputStreamResource commonInputStreamResource = null; try {commonInputStreamResource = new CommonInputStreamResource(fileInputStream,fileInputStream.available(),file.getName()); } catch (Exception e) {log.error("文件输入流转换错误:",e); } MultiValueMap dto=new LinkedMultiValueMap(); dto.add("cookie","xxx"); dto.add("file",commonInputStreamResource); dto.add("seqNoFile","xxx"); String returnInfo = taxRecodeFeignClient.attachFileUpload(dto); JSONObject returnInfoJsonObject = JSONObject.parseObject(returnInfo); }catch (Exception e){log.error("异常:",e); }}


    RestTemplate调用远程接口添加请求头 项目中我们经常会碰到与第三方系统对接,通过调用第三方系统中的接口来集成服务,为了接口的安全性都为加一些验证,比如:
    basic、authority等,通过请求头添加authrization的机制比较容易接入,从第三方系统获取到authorization,然后请求接口时在请求头上带上获取到的authorization,说了怎么多不如直接上代码更容易理解。
    // 获取第三方的authorizationString auth= OAuthContentHelper.getAuthorizationHeader(); HttpHeaders requestHeader=new HttpHeaders(); // 将获取到的authorization添加到请求头requestHeader.add(AuthConstants.AUTHORIZATION_HEADER,auth); // 构建请求实体HttpEntity requestEntity=new HttpEntity(requestParam,requestHeaders); // 使用restTemplate调用第三方接口restTemplate.exchage(url,HttpMethod.POST,requestEntity,responseClass);
    以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

      推荐阅读