在工作中我们会经常碰到调用别的系统接口的问题,如果是http接口的话,我们一般会选择使用HttpClient的来进行接口的调用。这篇文章就讲解下如何使用HttpClient调用别人的接口,主要从两个方面,第一种参数是map格式(post,get请求),第二种参数是json格式(psot,get请求)来展开讲解。
一、什么是HttpClient?
百度百科解释:HttpClient 是Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
通俗的解释:HttpClinet是以编程的方式(代码方式)模拟浏览器对接口进行访问从而进行数据的交互的工具包。
二、在什么场景下需要使用HttpClient?
1.需要调用其他系统接口时,尤其是基于HTTP协议的接口(我个人这种场景下使用HttpClient最多)
2.调用WebService接口(个人觉得不是特别好用)
三、为什么要使用HttpClient?
HttpClient实际上是对Java提供方法的一些封装,而HttpURLConnection是java的标准类,什么也没封装,用起来太原始,不方便。例如:在HttpURLConnection中的输入输出流操作,但是在HttpClient被统一封装成了HttpPost(HttpGet)和HttpResponse,这样就就减少了操作的繁琐性。可以类比,jdbc就相当于HttpURLConnection,MyBatis就相当于HttpClient。
四、怎么使用HttpClient?
1.使用方法:
①创建 HttpClient 的实例
②创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
③如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
④调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。
⑤调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
⑥ 释放连接。无论执行方法是否成功,都必须释放连接
2.Demo1:HttpClient模拟浏览器get请求,请求接口,参数格式类似于form表单的get形式(这里HttpClient版本是4.5.5)
maven依赖:
org.apache.httpcomponents
httpclient
4.5.5
org.apache.httpcomponents
httpmime
4.5.5
调用方代码(封装的HttpClient工具类的方法):
@Slf4j
public class HttpClientUtil {
private final static transient Log logger = LogFactory.getLog(HttpClientUtil.class);
public static final String CHARSET = "UTF-8";
public static final int CONNECT_TIMEOUT = 10 * 1000;
private static CloseableHttpClient httpClient;
static {
RequestConfig config = RequestConfig.custom()
.setConnectionRequestTimeout(CONNECT_TIMEOUT)//从连接池中获取可用连接最大超时时间
.setConnectTimeout(CONNECT_TIMEOUT)//连接目标url最大超时
.setSocketTimeout(CONNECT_TIMEOUT).build();//等待响应(读数据)最大超时
//创建HttpClient实例
httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
}
public static String doGet(String url, Map params,
String charset) {
if (StringUtils.isBlank(url)) {
return null;
}
try {//组装参数和url
if (params != null && !params.isEmpty()) {
List pairs = new ArrayList(
params.size());
for (Map.Entry entry : params.entrySet()) {
String value = entry.getValue();
if (value != null) {
pairs.add(new BasicNameValuePair(entry.getKey(), value));
}
}
url += "?"
+ EntityUtils.toString(new UrlEncodedFormEntity(pairs,
charset));
}
HttpGet httpGet = new HttpGet(url);//创建HttpGET
CloseableHttpResponse response = httpClient.execute(httpGet);//执行HttpGet请求
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200) {
httpGet.abort();
throw new RuntimeException("HttpClient,error status code :"
+ statusCode);
}
HttpEntity entity = response.getEntity();//获取响应的结果
String result = null;
if (entity != null) {
result = EntityUtils.toString(entity, "utf-8");//格式化响应的结果
}
EntityUtils.consume(entity);
response.close();
return result;
} catch (Exception e) {
logger.error(e.getMessage(),e);
}
return null;
}
public static void main(String[] args) {//测试的代码
String url="http://172.16.172.128:8081/denglu/hello";
String chset="UTF-8";
HashMap map = new HashMap<>();
map.put("name","dada1");
String s = doGet(url, map, chset);
System.out.println(s);
}
}
接口提供方代码(封装的HttpClient工具类中的方法):
@Controller
@RequestMapping(value = "/denglu")
public class UserController {
private final static transient Log logger = LogFactory.getLog(UserController.class);
@RequestMapping(value = "/hello",method = {RequestMethod.GET})//只能get方法访问
public @ResponseBody String home(@RequestParam Map map){
String name = map.get("name");
logger.info(name);
if (!"dada".equals(name)){
return "失败";
}
logger.info(map.toString());
return "hello";
}
}
调用结果:
被调用方的入参:
Demo2:HttpClient模拟浏览器post请求,请求接口,参数格式类似于form表单的post形式(这里HttpClient版本是4.5.5)
maven依赖:
org.apache.httpcomponents
httpclient
4.5.5
org.apache.httpcomponents
httpmime
4.5.5
调用方代码:
public static String doPost(String url, Map params,
String charset) {
if (StringUtils.isBlank(url)) {
return null;
}
try {//组装参数
List pairs= new ArrayList(
params.size());
if (params != null && !params.isEmpty()) {
for (Map.Entry entry : params.entrySet()) {
String value = entry.getValue();
if (value != null) {
pairs.add(new BasicNameValuePair(entry.getKey(), value));
}
}
}
HttpEntity intoEntity = new UrlEncodedFormEntity(pairs, "utf-8");//格式化参数并设置编码
HttpPost httpPost = new HttpPost(url);//创建HttpPost
httpPost.setEntity(intoEntity );//把参数放到请求体里
CloseableHttpResponse response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200) {
httpPost.abort();
throw new RuntimeException("HttpClient,error status code :"
+ statusCode);
}
HttpEntity entity = response.getEntity();//获取返回参数
String result = null;
if (entity != null) {
result = EntityUtils.toString(entity, "utf-8");
}
EntityUtils.consume(entity);
response.close();
return result;
} catch (Exception e) {
logger.error(e.getMessage(),e);
}
return null;
}
public static void main(String[] args) {//测试代码
String url="http://172.16.172.128:8081/denglu/hello";
String chset="UTF-8";
HashMap map = new HashMap<>();
map.put("name","dada");
String s = doPost(url, map, chset);
System.out.println(s);
}
接口提供方代码:
@Controller
@RequestMapping(value = "/denglu")
public class UserController {
private final static transient Log logger = LogFactory.getLog(UserController.class);
@RequestMapping(value = "/hello",method = {RequestMethod.POST})//只能post请求访问
public @ResponseBody String home(@RequestParam Map map){
String name = map.get("name");
logger.info(name);
if (!"dada".equals(name)){
return "失败";
}
logger.info(map.toString());
return "hello";
}
}
调用结果:
被调用方的入参:
Demo3:HttpClient模拟浏览器post请求,请求接口,参数格式json格式(这里HttpClient版本是4.5.5)
maven依赖:
org.apache.httpcomponents
httpclient
4.5.5
org.apache.httpcomponents
httpmime
4.5.5
调用方代码(封装的HttpClient工具类的方法):
public static String doPostJson(String url, String json) throws ClientProtocolException, IOException {
if (StringUtils.isBlank(url)) {
return null;
}
// 创建http POST请求
HttpPost httpPost = new HttpPost(url);
if (json != null) {
// 构造一个form表单式的实体
StringEntity stringEntity = new StringEntity(json, ContentType.APPLICATION_JSON);
// 将请求实体设置到httpPost对象中
httpPost.setEntity(stringEntity);
}
CloseableHttpResponse response = null;
try {
// 执行请求
response = httpClient.execute(httpPost);
log.info("POST 访问url:" + url + " 状态为: " + response.getStatusLine().getStatusCode());
String re = EntityUtils.toString(response.getEntity(), "UTF-8");
log.info("返回结果为: "+re);
return re;
} finally {
if (response != null) {
response.close();
}
}
}
public static void main(String[] args) throws IOException {//测试代码
String url="http://172.16.172.128:8081/denglu/hello";
String str="{'name':'dada'}";
//字符串转map
JSONObject jsonObject = JSONObject.parseObject(str);
Map map = (Map)jsonObject;// //json对象转Map
//map转字符串
String jsonString = JSON.toJSONString(map);
String s = doPostJson(url, jsonString);
System.out.println(s);
}
接口提供方代码:
@RequestMapping(value = "/hello",method = {RequestMethod.POST})
public @ResponseBody String home(@RequestBody JSONObject object){
Map map = JSONObject.toJavaObject(object, Map.class);
String name = (String) map.get("name");
logger.info(name);
if (!"dada".equals(name)){
return "失败";
}
logger.info(map.toString());
return "hello";
}
参考文章地址:
https://www.imooc.com/article/70192
http://www.cnblogs.com/langtianya/p/4001499.html
上面的三个demo比较简单,但是主要让大家熟悉封装HttpClient工具类的思路,基本上按照开头的6个步骤去写代码就不会有太大的问题,根据实际开发的需求可以灵活封装HttpClient工具类的方法。我是阿达,一名喜欢分享知识的程序员,时不时的也会荒腔走板的聊一聊电影、电视剧、音乐、漫画,这里已经有17位小伙伴在等你们啦,感兴趣的就赶紧来点击关注我把,哪里不明白或有不同观点的地方欢迎留言。