使用RestTemplate 调用远程接口上传文件方式
程序员文章站
2022-03-18 23:07:09
目录resttemplate 调用远程接口上传文件resttemplate调用远程接口添加请求头resttemplate 调用远程接口上传文件问题描述第三方写了一个文件上传的接口,该接口的请求方式为p...
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} */ @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);
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。