一、概述
在实际开发过程中,我们经常需要调用对方提供的接口或测试自己写的接口是否合适。很多项目都会封装规定好本身项目的接口规范,所以大多数需要去调用对方提供的接口或第三方接口(短信、天气等)。
在java项目中调用第三方接口的方式有:
1、通过jdk网络类java.net.httpurlconnection;
2、通过common封装好的httpclient;
3、通过apache封装好的closeablehttpclient;
4、通过springboot-resttemplate;
二、 java调用第三方http接口的方式
2.1、通过jdk网络类java.net.httpurlconnection
比较原始的一种调用做法,这里把get请求和post请求都统一放在一个方法里面。
实现过程:
get:
1、创建远程连接
2、设置连接方式(get、post、put。。。)
3、设置连接超时时间
4、设置响应读取时间
5、发起请求
6、获取请求数据
7、关闭连接
post:
1、创建远程连接
2、设置连接方式(get、post、put。。。)
3、设置连接超时时间
4、设置响应读取时间
5、当向远程服务器传送数据/写数据时,需要设置为true(setdooutput)
6、当前向远程服务读取数据时,设置为true,该参数可有可无(setdoinput)
7、设置传入参数的格式:(setrequestproperty)
8、设置鉴权信息:authorization:(setrequestproperty)
9、设置参数
10、发起请求
11、获取请求数据
12、关闭连接
直接上代码:
package com.riemann.springbootdemo.util.common.httpconnectionutil;
import org.springframework.lang.nullable;
import java.io.*;
import java.net.httpurlconnection;
import java.net.malformedurlexception;
import java.net.url;
import java.net.urlconnection;
/**
* @author riemann
* @date 2019/05/24 23:42
*/
public class httpurlconnectionutil {
/**
* http get请求
* @param httpurl 连接
* @return 响应数据
*/
public static string doget(string httpurl){
//链接
httpurlconnection connection = null;
inputstream is = null;
bufferedreader br = null;
stringbuffer result = new stringbuffer();
try {
//创建连接
url url = new url(httpurl);
connection = (httpurlconnection) url.openconnection();
//设置请求方式
connection.setrequestmethod("get");
//设置连接超时时间
connection.setreadtimeout(15000);
//开始连接
connection.connect();
//获取响应数据
if (connection.getresponsecode() == 200) {
//获取返回的数据
is = connection.getinputstream();
if (null != is) {
br = new bufferedreader(new inputstreamreader(is, "utf-8"));
string temp = null;
while (null != (temp = br.readline())) {
result.append(temp);
}
}
}
} catch (ioexception e) {
e.printstacktrace();
} finally {
if (null != br) {
try {
br.close();
} catch (ioexception e) {
e.printstacktrace();
}
}
if (null != is) {
try {
is.close();
} catch (ioexception e) {
e.printstacktrace();
}
}
//关闭远程连接
connection.disconnect();
}
return result.tostring();
}
/**
* http post请求
* @param httpurl 连接
* @param param 参数
* @return
*/
public static string dopost(string httpurl, @nullable string param) {
stringbuffer result = new stringbuffer();
//连接
httpurlconnection connection = null;
outputstream os = null;
inputstream is = null;
bufferedreader br = null;
try {
//创建连接对象
url url = new url(httpurl);
//创建连接
connection = (httpurlconnection) url.openconnection();
//设置请求方法
connection.setrequestmethod("post");
//设置连接超时时间
connection.setconnecttimeout(15000);
//设置读取超时时间
connection.setreadtimeout(15000);
//dooutput设置是否向httpurlconnection输出,doinput设置是否从httpurlconnection读入,此外发送post请求必须设置这两个
//设置是否可读取
connection.setdooutput(true);
connection.setdoinput(true);
//设置通用的请求属性
connection.setrequestproperty("accept", "*/*");
connection.setrequestproperty("connection", "keep-alive");
connection.setrequestproperty("user-agent", "mozilla/4.0 (compatible; msie 6.0; windows nt 5.1; sv1)");
connection.setrequestproperty("content-type", "application/json;charset=utf-8");
//拼装参数
if (null != param && param.equals("")) {
//设置参数
os = connection.getoutputstream();
//拼装参数
os.write(param.getbytes("utf-8"));
}
//设置权限
//设置请求头等
//开启连接
//connection.connect();
//读取响应
if (connection.getresponsecode() == 200) {
is = connection.getinputstream();
if (null != is) {
br = new bufferedreader(new inputstreamreader(is, "gbk"));
string temp = null;
while (null != (temp = br.readline())) {
result.append(temp);
result.append("\r\n");
}
}
}
} catch (malformedurlexception e) {
e.printstacktrace();
} catch (ioexception e) {
e.printstacktrace();
} finally {
//关闭连接
if(br!=null){
try {
br.close();
} catch (ioexception e) {
e.printstacktrace();
}
}
if(os!=null){
try {
os.close();
} catch (ioexception e) {
e.printstacktrace();
}
}
if(is!=null){
try {
is.close();
} catch (ioexception e) {
e.printstacktrace();
}
}
//关闭连接
connection.disconnect();
}
return result.tostring();
}
public static void main(string[] args) {
string message = dopost("https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13026194071", "");
system.out.println(message);
}
}
运行结果:

2.2 通过apache common封装好的httpclient
httpclient的get或post请求方式步骤:
- 生成一个httpclient对象并设置相应的参数;
- 生成一个getmethod对象或postmethod并设置响应的参数;
- 用httpclient生成的对象来执行getmethod生成的get方法;
- 处理响应状态码;
- 若响应正常,处理http响应内容;
- 释放连接。
导入如下jar包:
<!--httpclient-->
<dependency>
<groupid>commons-httpclient</groupid>
<artifactid>commons-httpclient</artifactid>
<version>3.1</version>
</dependency>
<!--fastjson-->
<dependency>
<groupid>com.alibaba</groupid>
<artifactid>fastjson</artifactid>
<version>1.2.32</version>
</dependency>
代码如下:
package com.riemann.springbootdemo.util.common.httpconnectionutil;
import com.alibaba.fastjson.jsonobject;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.getmethod;
import org.apache.commons.httpclient.methods.postmethod;
import org.apache.commons.httpclient.params.httpmethodparams;
import java.io.ioexception;
/**
* @author riemann
* @date 2019/05/25 0:58
*/
public class httpclientutil {
/**
* httpclient的get请求方式
* 使用getmethod来访问一个url对应的网页实现步骤:
* 1.生成一个httpclient对象并设置相应的参数;
* 2.生成一个getmethod对象并设置响应的参数;
* 3.用httpclient生成的对象来执行getmethod生成的get方法;
* 4.处理响应状态码;
* 5.若响应正常,处理http响应内容;
* 6.释放连接。
* @param url
* @param charset
* @return
*/
public static string doget(string url, string charset) {
//1.生成httpclient对象并设置参数
httpclient httpclient = new httpclient();
//设置http连接超时为5秒
httpclient.gethttpconnectionmanager().getparams().setconnectiontimeout(5000);
//2.生成getmethod对象并设置参数
getmethod getmethod = new getmethod(url);
//设置get请求超时为5秒
getmethod.getparams().setparameter(httpmethodparams.so_timeout, 5000);
//设置请求重试处理,用的是默认的重试处理:请求三次
getmethod.getparams().setparameter(httpmethodparams.retry_handler, new defaulthttpmethodretryhandler());
string response = "";
//3.执行http get 请求
try {
int statuscode = httpclient.executemethod(getmethod);
//4.判断访问的状态码
if (statuscode != httpstatus.sc_ok) {
system.err.println("请求出错:" + getmethod.getstatusline());
}
//5.处理http响应内容
//http响应头部信息,这里简单打印
header[] headers = getmethod.getresponseheaders();
for(header h : headers) {
system.out.println(h.getname() + "---------------" + h.getvalue());
}
//读取http响应内容,这里简单打印网页内容
//读取为字节数组
byte[] responsebody = getmethod.getresponsebody();
response = new string(responsebody, charset);
system.out.println("-----------response:" + response);
//读取为inputstream,在网页内容数据量大时候推荐使用
//inputstream response = getmethod.getresponsebodyasstream();
} catch (httpexception e) {
//发生致命的异常,可能是协议不对或者返回的内容有问题
system.out.println("请检查输入的url!");
e.printstacktrace();
} catch (ioexception e) {
//发生网络异常
system.out.println("发生网络异常!");
} finally {
//6.释放连接
getmethod.releaseconnection();
}
return response;
}
/**
* post请求
* @param url
* @param json
* @return
*/
public static string dopost(string url, jsonobject json){
httpclient httpclient = new httpclient();
postmethod postmethod = new postmethod(url);
postmethod.addrequestheader("accept", "*/*");
postmethod.addrequestheader("connection", "keep-alive");
//设置json格式传送
postmethod.addrequestheader("content-type", "application/json;charset=gbk");
//必须设置下面这个header
postmethod.addrequestheader("user-agent", "mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/58.0.3029.81 safari/537.36");
//添加请求参数
postmethod.addparameter("commentid", json.getstring("commentid"));
string res = "";
try {
int code = httpclient.executemethod(postmethod);
if (code == 200){
res = postmethod.getresponsebodyasstring();
system.out.println(res);
}
} catch (ioexception e) {
e.printstacktrace();
}
return res;
}
public static void main(string[] args) {
system.out.println(doget("http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13026194071", "gbk"));
system.out.println("-----------分割线------------");
system.out.println("-----------分割线------------");
system.out.println("-----------分割线------------");
jsonobject jsonobject = new jsonobject();
jsonobject.put("commentid", "13026194071");
system.out.println(dopost("http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13026194071", jsonobject));
}
}
运行结果:

post请求的jsonobject 的参数也成功写入
2.3 通过apache封装好的closeablehttpclient
closeablehttpclient是在httpclient的基础上修改更新而来的,这里还涉及到请求头token的设置(请求验证),利用fastjson转换请求或返回结果字符串为json格式,当然上面两种方式也是可以设置请求头token、json的,这里只在下面说明。
导入如下jar包:
<!--closeablehttpclient-->
<dependency>
<groupid>org.apache.httpcomponents</groupid>
<artifactid>httpclient</artifactid>
<version>4.5.2</version>
</dependency>
<!--fastjson-->
<dependency>
<groupid>com.alibaba</groupid>
<artifactid>fastjson</artifactid>
<version>1.2.32</version>
</dependency>
代码如下:
package com.riemann.springbootdemo.util.common.httpconnectionutil;
import com.alibaba.fastjson.jsonobject;
import org.apache.http.httpresponse;
import org.apache.http.httpstatus;
import org.apache.http.client.methods.closeablehttpresponse;
import org.apache.http.client.methods.httpget;
import org.apache.http.client.methods.httppost;
import org.apache.http.entity.stringentity;
import org.apache.http.impl.client.closeablehttpclient;
import org.apache.http.impl.client.httpclientbuilder;
import org.apache.http.util.entityutils;
import java.io.ioexception;
import java.io.unsupportedencodingexception;
/**
* @author riemann
* @date 2019/05/25 1:35
*/
public class closeablehttpclientutil {
private static string tokenstring = "";
private static string auth_token_expired = "auth_token_expired";
private static closeablehttpclient httpclient = null;
/**
* 以get方式调用第三方接口
* @param url
* @param token
* @return
*/
public static string doget(string url, string token) {
//创建httpclient对象
closeablehttpclient httpclient = httpclientbuilder.create().build();
httpget httpget = new httpget(url);
if (null != tokenstring && !tokenstring.equals("")) {
tokenstring = gettoken();
}
//api_gateway_auth_token自定义header头,用于token验证使用
httpget.addheader("api_gateway_auth_token",tokenstring);
httpget.addheader("user-agent", "mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/58.0.3029.81 safari/537.36");
try {
httpresponse response = httpclient.execute(httpget);
if (response.getstatusline().getstatuscode() == httpstatus.sc_ok) {
//返回json格式
string res = entityutils.tostring(response.getentity());
return res;
}
} catch (ioexception e) {
e.printstacktrace();
}
return null;
}
/**
* 以post方式调用第三方接口
* @param url
* @param json
* @return
*/
public static string dopost(string url, jsonobject json) {
if (null == httpclient) {
httpclient = httpclientbuilder.create().build();
}
httppost httppost = new httppost(url);
if (null != tokenstring && tokenstring.equals("")) {
tokenstring = gettoken();
}
//api_gateway_auth_token自定义header头,用于token验证使用
httppost.addheader("api_gateway_auth_token", tokenstring);
httppost.addheader("user-agent", "mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/58.0.3029.81 safari/537.36");
try {
stringentity se = new stringentity(json.tostring());
se.setcontentencoding("utf-8");
//发送json数据需要设置contenttype
se.setcontenttype("application/x-www-form-urlencoded");
//设置请求参数
httppost.setentity(se);
httpresponse response = httpclient.execute(httppost);
if (response.getstatusline().getstatuscode() == httpstatus.sc_ok) {
//返回json格式
string res = entityutils.tostring(response.getentity());
return res;
}
} catch (ioexception e) {
e.printstacktrace();
} finally {
if (httpclient != null){
try {
httpclient.close();
} catch (ioexception e) {
e.printstacktrace();
}
}
}
return null;
}
/**
* 获取第三方接口的token
*/
public static string gettoken() {
string token = "";
jsonobject object = new jsonobject();
object.put("appid", "appid");
object.put("secretkey", "secretkey");
if (null == httpclient) {
httpclient = httpclientbuilder.create().build();
}
httppost httppost = new httppost("http://localhost/login");
httppost.addheader("user-agent", "mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/58.0.3029.81 safari/537.36");
try {
stringentity se = new stringentity(object.tostring());
se.setcontentencoding("utf-8");
//发送json数据需要设置contenttype
se.setcontenttype("application/x-www-form-urlencoded");
//设置请求参数
httppost.setentity(se);
httpresponse response = httpclient.execute(httppost);
//这里可以把返回的结果按照自定义的返回数据结果,把string转换成自定义类
//resulttokenbo result = jsonobject.parseobject(response, resulttokenbo.class);
//把response转为jsonobject
jsonobject result = (jsonobject) jsonobject.parseobject(string.valueof(response));
if (result.containskey("token")) {
token = result.getstring("token");
}
} catch (ioexception e) {
e.printstacktrace();
}
return token;
}
/**
* 测试
*/
public static void test(string telephone) {
jsonobject object = new jsonobject();
object.put("telephone", telephone);
//首先获取token
tokenstring = gettoken();
string response = dopost("http://localhost/searchurl", object);
//如果返回的结果是list形式的,需要使用jsonobject.parsearray转换
//list<result> list = jsonobject.parsearray(response, result.class);
system.out.println(response);
}
public static void main(string[] args) {
test("12345678910");
}
}
2.4 通过springboot-resttemplate
springboot-resttemple是上面三种方式的集大成者,代码编写更加简单,目前可以采用的调用第三方接口有:
- delete() 在特定的url上对资源执行http delete操作
- exchange() 在url上执行特定的http方法,返回包含对象的responseentity,这个对象是从响应体中映射得到的
- execute() 在url上执行特定的http方法,返回一个从响应体映射得到的对象
- getforentity() 发送一个http get请求,返回的responseentity包含了响应体所映射成的对象
- getforobject() 发送一个http get请求,返回的请求体将映射为一个对象
- postforentity() post 数据到一个url,返回包含一个对象的responseentity,这个对象是从响应体中映射得到的
- postforobject() post 数据到一个url,返回根据响应体匹配形成的对象
- headforheaders() 发送http head请求,返回包含特定资源url的http头
- optionsforallow() 发送http options请求,返回对特定url的allow头信息
- postforlocation() post 数据到一个url,返回新创建资源的url
- put() put 资源到特定的url
注意:目前标粗的为常用的
首先导入springboot的web包
<parent>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-parent</artifactid>
<version>2.0.4.release</version>
</parent>
<dependencies>
<!--closeablehttpclient-->
<dependency>
<groupid>org.apache.httpcomponents</groupid>
<artifactid>httpclient</artifactid>
<version>4.5.2</version>
</dependency>
<!--spring resttemplate-->
<!-- @configurationproperties annotation processing (metadata for ides)
生成spring-configuration-metadata.json类,需要引入此类-->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-configuration-processor</artifactid>
<optional>true</optional>
</dependency>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-aop</artifactid>
</dependency>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
<exclusions>
<exclusion>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-tomcat</artifactid>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-jetty</artifactid>
</dependency>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-test</artifactid>
<scope>test</scope>
</dependency>
</dependencies>
在启动类同包下创建resttemplateconfig.java类
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.http.client.clienthttprequestfactory;
import org.springframework.http.client.simpleclienthttprequestfactory;
import org.springframework.web.client.resttemplate;
/**
* @author riemann
* @date 2019/05/25 2:16
*/
@configuration
public class resttemplateconfig {
@bean
public resttemplate resttemplate(clienthttprequestfactory factory){
return new resttemplate(factory);
}
@bean
public clienthttprequestfactory simpleclienthttprequestfactory(){
simpleclienthttprequestfactory factory = new simpleclienthttprequestfactory();
factory.setconnecttimeout(15000);
factory.setreadtimeout(5000);
return factory;
}
}
然后在service类(resttemplatetointerface )中注入使用
具体代码如下:
import com.alibaba.fastjson.jsonobject;
import com.swordfall.model.user;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.http.*;
import org.springframework.stereotype.service;
import org.springframework.web.client.resttemplate;
/**
* @author riemann
* @date 2019/05/25 2:20
*/
@service
public class resttemplatetointerface {
@autowired
private resttemplate resttemplate;
/**
* 以get方式请求第三方http接口 getforentity
* @param url
* @return
*/
public user dogetwith1(string url){
responseentity<user> responseentity = resttemplate.getforentity(url, user.class);
user user = responseentity.getbody();
return user;
}
/**
* 以get方式请求第三方http接口 getforobject
* 返回值返回的是响应体,省去了我们再去getbody()
* @param url
* @return
*/
public user dogetwith2(string url){
user user = resttemplate.getforobject(url, user.class);
return user;
}
/**
* 以post方式请求第三方http接口 postforentity
* @param url
* @return
*/
public string dopostwith1(string url){
user user = new user("小白", 20);
responseentity<string> responseentity = resttemplate.postforentity(url, user, string.class);
string body = responseentity.getbody();
return body;
}
/**
* 以post方式请求第三方http接口 postforentity
* @param url
* @return
*/
public string dopostwith2(string url){
user user = new user("小白", 20);
string body = resttemplate.postforobject(url, user, string.class);
return body;
}
/**
* exchange
* @return
*/
public string doexchange(string url, integer age, string name){
//header参数
httpheaders headers = new httpheaders();
string token = "asdfaf2322";
headers.add("authorization", token);
headers.setcontenttype(mediatype.application_json);
//放入body中的json参数
jsonobject obj = new jsonobject();
obj.put("age", age);
obj.put("name", name);
//组装
httpentity<jsonobject> request = new httpentity<>(obj, headers);
responseentity<string> responseentity = resttemplate.exchange(url, httpmethod.post, request, string.class);
string body = responseentity.getbody();
return body;
}
}
2021.3.14 更新
应大家的响应,okhttp 现在也是蛮流行的,基于手机端很火,这里分享一下okhttpclient客户端,业务代码get、post请求直接调用就好哈。
2.5 通过okhttp
pom文件引入依赖包
<dependency>
<groupid>com.squareup.okhttp3</groupid>
<artifactid>okhttp</artifactid>
<version>3.10.0</version>
</dependency>
@slf4j
public class okhttpclient {
private static final mediatype json = mediatype.parse("application/json; charset=utf-8");
private volatile static okhttp3.okhttpclient client;
private static final int max_idle_connection = integer
.parseint(configmanager.get("httpclient.max_idle_connection"));
private static final long keep_alive_duration = long
.parselong(configmanager.get("httpclient.keep_alive_duration"));
private static final long connect_timeout = long.parselong(configmanager.get("httpclient.connecttimeout"));
private static final long read_timeout = long.parselong(configmanager.get("httpclient. "));
/**
* 单例模式(双重检查模式) 获取类实例
*
* @return client
*/
private static okhttp3.okhttpclient getinstance() {
if (client == null) {
synchronized (okhttp3.okhttpclient.class) {
if (client == null) {
client = new okhttp3.okhttpclient.builder()
.connecttimeout(connect_timeout, timeunit.seconds)
.readtimeout(read_timeout, timeunit.seconds)
.connectionpool(new connectionpool(max_idle_connection, keep_alive_duration,
timeunit.minutes))
.build();
}
}
}
return client;
}
public static string syncpost(string url, string json) throws ioexception {
requestbody body = requestbody.create(json, json);
request request = new request.builder()
.url(url)
.post(body)
.build();
try {
response response = okhttpclient.getinstance().newcall(request).execute();
if (response.issuccessful()) {
string result = response.body().string();
log.info("syncpost response = {}, responsebody= {}", response, result);
return result;
}
string result = response.body().string();
log.info("syncpost response = {}, responsebody= {}", response, result);
throw new ioexception("三方接口返回http状态码为" + response.code());
} catch (exception e) {
log.error("syncpost() url:{} have a ecxeption {}", url, e);
throw new runtimeexception("syncpost() have a ecxeption {}" + e.getmessage());
}
}
public static string syncget(string url, map<string, object> headparamsmap) throws ioexception {
request request;
final request.builder builder = new request.builder().url(url);
try {
if (!collectionutils.isempty(headparamsmap)) {
final iterator<map.entry<string, object>> iterator = headparamsmap.entryset()
.iterator();
while (iterator.hasnext()) {
final map.entry<string, object> entry = iterator.next();
builder.addheader(entry.getkey(), (string) entry.getvalue());
}
}
request = builder.build();
response response = okhttpclient.getinstance().newcall(request).execute();
string result = response.body().string();
log.info("syncget response = {},responsebody= {}", response, result);
if (!response.issuccessful()) {
throw new ioexception("三方接口返回http状态码为" + response.code());
}
return result;
} catch (exception e) {
log.error("remote interface url:{} have a ecxeption {}", url, e);
throw new runtimeexception("三方接口返回异常");
}
}
}到此这篇关于java实现调用http请求的五种常见方式的文章就介绍到这了,更多相关java 调用http请求内容请搜索3w代码以前的文章或继续浏览下面的相关文章希望大家以后多多支持3w代码!
发表评论