如何使用RestTemplate调用远程接口上传文件

发布时间:2021-09-26 09:11:41 作者:柒染
来源:亿速云 阅读:319

今天就跟大家聊聊有关如何使用RestTemplate调用远程接口上传文件,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

RestTemplate 调用远程接口上传文件

问题描述

第三方写了一个文件上传的接口,该接口的请求方式为Post请求,请求参数全部是以form-data表单形式进行提交,包含三个参数

解决方法

使用传统的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}
     */
    @Override
    public String getFilename() {
        return fileName;
    }
 
    /**
     * 覆写父类 contentLength 方法
     * 因为 {@link org.springframework.core.io.AbstractResource#contentLength()}方法会重新读取一遍文件,
     * 而上传文件时,restTemplate 会通过这个方法获取大小。然后当真正需要读取内容的时候,发现已经读完,会报如下错误。
     */
    @Override
    public 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<String, Object> 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<MultiValueMap> requestEntity = new HttpEntity<MultiValueMap>(requestBody, requestHeaders);
    
    //直接调用远程接口
    ResponseEntity<String> 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 = "/attachFile/upload",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    String attachFileUpload(MultiValueMap<String, Object> 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<String, Object> dto=new LinkedMultiValueMap<String, Object>();
        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,说了怎么多不如直接上代码更容易理解。

// 获取第三方的authorization
String auth= OAuthContentHelper.getAuthorizationHeader();
HttpHeaders requestHeader=new HttpHeaders();
// 将获取到的authorization添加到请求头
requestHeader.add(AuthConstants.AUTHORIZATION_HEADER,auth);
// 构建请求实体
HttpEntity<Object> requestEntity=new HttpEntity(requestParam,requestHeaders);
// 使用restTemplate调用第三方接口
restTemplate.exchage(url,HttpMethod.POST,requestEntity,responseClass);

看完上述内容,你们对如何使用RestTemplate调用远程接口上传文件有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。

推荐阅读:
  1. SpringBoot如何使用feign实现远程接口调用和错误熔断
  2. 如何在Laravel中使用Gin接口调用formData上传文件

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

resttemplate

上一篇:一般用爬虫会遇到什么问题

下一篇:动态静态网页指的是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》