在日常工作中,经常需要跟第三方系统对接,我们做为客户端,调用他们的接口进行业务处理
常用的几种调用方式有:
- 1.原生的java.net.httpurlconnection(jdk);
- 2.再次封装的httpclient、closeablehttpclient(apache);
- 3.spring提供的resttemplate;
当然还有其他工具类进行封装的接口,比如hutool的httputil工具类,里面除了post、get请求外,还有下载文件的方法downloadfile等。
httpurlconnection调用方法
http正文的内容是通过outputstream流写入,向流中写入的数据不会立即发送到网络,而是存在于内存缓冲区中,待流关闭时,根据写入的内容生成http正文。
调用getinputstream()方法时,会返回一个输入流,用于从中读取服务器对于http请求的返回报文
@slf4j
public class httpurlconnectionutil {
/**
*
* description: 发送http请求发送post和json格式
* @param url 请求url
* @param params json格式的请求参数
*/
public static string dopost(string url, string params) throws exception {
outputstreamwriter out = null;
bufferedreader reader = null;
stringbuffer response = new stringbuffer();
url httpurl = null; // http url类 用这个类来创建连接
try {
// 创建url
httpurl = new url(url);
log.info("--------发起http post 请求 ------------- url:" + url + "---------params:" + params);
// 建立连接
httpurlconnection conn = (httpurlconnection) httpurl.openconnection();
//设置请求的方法为"post",默认是get
conn.setrequestmethod("post");
conn.setrequestproperty("content-type", "application/json");
conn.setrequestproperty("connection", "keep-alive");
conn.setusecaches(false);// 设置不要缓存
conn.setinstancefollowredirects(true);
//由于urlconnection在默认的情况下不允许输出,所以在请求输出流之前必须调用setdooutput(true)
conn.setdooutput(true);
// 设置是否从httpurlconnection读入
conn.setdoinput(true);
//设置超时时间
conn.setconnecttimeout(30000);
conn.setreadtimeout(30000);
conn.connect();
// post请求
out = new outputstreamwriter(conn.getoutputstream());
out.write(params);
out.flush();
// 读取响应
reader = new bufferedreader(new inputstreamreader(conn.getinputstream(), "utf-8"));
string lines;
while ((lines = reader.readline()) != null) {
response.append(lines);
}
reader.close();
// 断开连接
conn.disconnect();
} catch (exception e) {
log.error("--------发起http post 请求 异常 {}-------------", e);
throw new exception(e);
}
// 使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (reader != null) {
reader.close();
}
} catch (ioexception ex) {
log.error(string.valueof(ex));
}
}
return response.tostring();
}
}closeablehttpclient调用
closeablehttpclient 是一个抽象类,实现了httpclient接口,也实现了java.io.closeable;
支持连接池管理,可复用已建立的连接 poolinghttpclientconnectionmanager
通过 httpclient.close() 自动管理连接释放
支持https访问 httphost proxy = new httphost(“127.0.0.1”, 8080, “http”);
@slf4j
public class closeablehttpclientutil {
/**
*url 第三方接口地址
*json 传入的报文体,可以是dto对象,string、json等
*header 额外传入的请求头参数
*/
public static string dopost(string url, object json,map<string,string> header) {
closeablehttpclient httpclient = httpclientbuilder.create().build();
httppost httppost= new httppost(url);//post请求类型
string result="";//返回结果
string requestjson="";//发送报文体
try {
requestjson=jsonobject.tojsonstring(json);
log.info("发送地址:"+url+"发送报文:"+requestjson);
//stringentity s = new stringentity(requestjson, charset.forname("utf-8"));
stringentity s= new stringentity(requestjson, "utf-8");
// post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
httppost.setheader("content-type", "application/json;charset=utf8");
httppost.setentity(s);
if(header!=null){
set<string> strings = header.keyset();
for(string str:strings){
httppost.setheader(str,header.get(str));
}
}
httpresponse res = httpclient.execute(httppost);
if (res.getstatusline().getstatuscode() == httpstatus.sc_ok) {
result = entityutils.tostring(res.getentity());
//也可以把返回的报文转成json类型
// jsonobject response = jsonobject.parseobject(result);
}
} catch (exception e) {
throw new runtimeexception(e);
}
finally {
//此处可以加入记录日志的方法
// 关闭连接,释放资源
if (httpclient!= null){
try {
httpclient.close();
} catch (ioexception e) {
e.printstacktrace();
}
}
}
return result;
}
}resttemplate调用
//可以在项目启动类中添加resttemplate 的bean,后续就可以在代码中@autowired引入。
@bean
public resttemplate resttemplate() {
return new resttemplate();
}@slf4j
@component
public class resttemplateutils {
@autowired
private resttemplate resttemplate;
/**
* get 请求 参数在url后面 http://xxxx?aa=xxx&page=0&size=10";
* @param urls
* @return string
*/
public string dogetrequest(string urls) {
uri uri = uricomponentsbuilder.fromuristring(urls).build().touri();
log.info("请求接口:{}", urls);
httpheaders headers = new httpheaders();
headers.setcontenttype(mediatype.application_json);
httpentity<string> httpentity = new httpentity<>(headers);
//通用的方法exchange,这个方法需要你在调用的时候去指定请求类型,可以是get,post,也能是其它类型的请求
responseentity<string> responseentity = resttemplate.exchange(uri, httpmethod.get, httpentity, string.class);
if (responseentity == null) {
return null;
}
log.info("返回报文:{}", json.tojsonstring(responseentity));
return responseentity.getbody();
}
/**
* post 请求 参数在 request里;
* @param url, request
* @return string
*/
public string dopostrequest(string url, object request){
uri uri = uricomponentsbuilder.fromuristring(url).build().touri();
string requeststr= jsonobject.tojsonstring(request);
log.info("请求接口:{}, 请求报文:{}", url, requeststr);
httpheaders headers = new httpheaders();
headers.setcontenttype(mediatype.application_json);
httpentity<string> httpentity = new httpentity<>(requeststr, headers);
responseentity<string> responseentity = resttemplate.exchange(uri, httpmethod.post, httpentity, string.class);
if (responseentity == null) {
return null;
}
string seqresult = "";
try {
if(responseentity.getbody() != null ) {
if(responseentity.getbody().contains("9001")) {
seqresult = new string(responseentity.getbody().getbytes("iso8859-1"),"utf-8");
}else {
seqresult = new string(responseentity.getbody().getbytes(),"utf-8");
}
}
log.info("返回报文:{}", seqresult);
} catch (unsupportedencodingexception e) {
log.error("接口返回异常", e);
}
return seqresult;
}
}总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论