⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 blog.csdn.net/qq_35860138/article/details/82967727 「qq_35860138」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

在项目开发中经常会遇到调用第三方接口的情况,比如说调用第三方的天气预报接口。

【1】准备工作:

在项目的工具包下导入HttpClientUtil这个工具类,或者也可以使用Spring框架的restTemplate来调用,上面有调用接口的方法【分为Get和Post方式的有参和无参调用】:

package com.njsc.credit.util;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
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.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class HttpClientUtil {

/**
* 带参数的get请求
* @param url
* @param param
* @return String
*/
public static String doGet(String url, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();

String resultString = "";
CloseableHttpResponse response = null;
try {
// 创建uri
URIBuilder builder = new URIBuilder(url);
if (param != null) {
for (String key : param.keySet()) {
builder.addParameter(key, param.get(key));
}
}
URI uri = builder.build();
// 创建http GET请求
HttpGet httpGet = new HttpGet(uri);
// 执行请求
response = httpclient.execute(httpGet);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}

/**
* 不带参数的get请求
* @param url
* @return String
*/
public static String doGet(String url) {
return doGet(url, null);
}

/**
* 带参数的post请求
* @param url
* @param param
* @return String
*/
public static String doPost(String url, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建参数列表
if (param != null) {
List<NameValuePair> paramList = new ArrayList<>();
for (String key : param.keySet()) {
paramList.add(new BasicNameValuePair(key, param.get(key)));
}
// 模拟表单
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
httpPost.setEntity(entity);
}
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}

/**
* 不带参数的post请求
* @param url
* @return String
*/
public static String doPost(String url) {
return doPost(url, null);
}

/**
* 传送json类型的post请求
* @param url
* @param json
* @return String
*/
public static String doPostJson(String url, String json) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建请求内容
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
}

【2】创建url和访问key 以及参数等:

代码如下:

/**
* 聚合接口校验身份证
* @param idCard
* @param realName
* @return boolean
*/
public boolean identityCheck(String idCard, String realName){
logger.info("-----------------调用聚合数据 身份证验证API BEGIN--------------->");
String key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
String url = "http://op.juhe.cn/idcard/query" + "?key=" + key + "&idcard=" + idCard + "&realname=" + realName;
logger.info("请求url:" + url);
boolean match = false; //是否匹配
try {
String result = HttpClientUtil.doGet(url);
System.out.println("请求结果:" + result);
IdentityCheckResult identityCheckResult = JsonUtils.parse(result, IdentityCheckResult.class);
IdentityCheck identityCheck = JsonUtils.parse(result, "result", IdentityCheck.class);
logger.info(identityCheckResult);
logger.info(identityCheck.toString());
if(identityCheckResult.correct() && identityCheck.getRes() == 1){
match = true;
}
} catch (Exception e) {
e.printStackTrace();
}
logger.info("<-----------------调用聚合数据 身份证验证API END---------------");
return match;
}

【3】请求这个第三方接口:

使用HttpClientUtil工具类中的doGet方法来请求URL,得到结果,现在大多数是一个json字符串,类型为String

【4】根据接口返回数据格式来解析数据:

可以看到,返回参数有六个,所以在项目中新建一个bean,包含以上六个字段,用来接住返回数据,如下:

因为接口返回的数据是一个json的字符串,类型实际上是一个String字符串,要解析数据,用工具类JsonUtils的parse方法将字符串转换为Java对象,JsonUtils的代码如下:

package com.eqianxian.commons.utils.json;

import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.PropertyFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;

/**
* 在系统中统一使用这个,以方便将来切换不同的JSON生成工具
*
* @author KelvinZ
*
*/
public class JsonUtils {
public static final int TYPE_FASTJSON = 0;
public static final int TYPE_GSON = 1;

/**
* <pre>
* 对象转化为json字符串
*
* @param obj 待转化对象
* @return 代表该对象的Json字符串
*/
public static final String toJson(final Object obj) {
return JSON.toJSONString(obj);
// return gson.toJson(obj);
}

/**
* <pre>
* 对象转化为json字符串
*
* @param obj 待转化对象
* @return 代表该对象的Json字符串
*/
public static final String toJson(final Object obj, SerializerFeature... features) {
return JSON.toJSONString(obj, features);
// return gson.toJson(obj);
}

/**
* 对象转化为json字符串并格式化
*
* @param obj
* @param format 是否要格式化
* @return
*/
public static final String toJson(final Object obj, final boolean format) {
return JSON.toJSONString(obj, format);
}

/**
* 对象对指定字段进行过滤处理,生成json字符串
*
* @param obj
* @param fields 过滤处理字段
* @param ignore true做忽略处理,false做包含处理
* @param features json特征,为null忽略
* @return
*/
public static final String toJson(final Object obj, final String[] fields, final boolean ignore,
SerializerFeature... features) {
if (fields == null || fields.length < 1) {
return toJson(obj);
}
if (features == null)
features = new SerializerFeature[] { SerializerFeature.QuoteFieldNames };
return JSON.toJSONString(obj, new PropertyFilter() {
@Override
public boolean apply(Object object, String name, Object value) {
for (int i = 0; i < fields.length; i++) {
if (name.equals(fields[i])) {
return !ignore;
}
}
return ignore;
}
}, features);
}

/**
* <pre>
* 解析json字符串中某路径的值
*
* @param json
* @param path
* @return
*/
@SuppressWarnings("unchecked")
public static final <E> E parse(final String json, final String path) {
String[] keys = path.split(",");
JSONObject obj = JSON.parseObject(json);
for (int i = 0; i < keys.length - 1; i++) {
obj = obj.getJSONObject(keys[i]);
}
return (E) obj.get(keys[keys.length - 1]);
}

/**
* <pre>
* json字符串解析为对象
*
* @param json 代表一个对象的Json字符串
* @param clazz 指定目标对象的类型,即返回对象的类型
* @return 从json字符串解析出来的对象
*/
public static final <T> T parse(final String json, final Class<T> clazz) {
return JSON.parseObject(json, clazz);
}

/**
* <pre>
* json字符串解析为对象
*
* @param json json字符串
* @param path 逗号分隔的json层次结构
* @param clazz 目标类
*/
public static final <T> T parse(final String json, final String path, final Class<T> clazz) {
String[] keys = path.split(",");
JSONObject obj = JSON.parseObject(json);
for (int i = 0; i < keys.length - 1; i++) {
obj = obj.getJSONObject(keys[i]);
}
String inner = obj.getString(keys[keys.length - 1]);
return parse(inner, clazz);
}

/**
* 将制定的对象经过字段过滤处理后,解析成为json集合
*
* @param obj
* @param fields
* @param ignore
* @param clazz
* @param features
* @return
*/
public static final <T> List<T> parseArray(final Object obj, final String[] fields, boolean ignore,
final Class<T> clazz, final SerializerFeature... features) {
String json = toJson(obj, fields, ignore, features);
return parseArray(json, clazz);
}

/**
* <pre>
* 从json字符串中解析出一个对象的集合,被解析字符串要求是合法的集合类型
* (形如:["k1":"v1","k2":"v2",..."kn":"vn"])
*
* @param json - [key-value-pair...]
* @param clazz
* @return
*/
public static final <T> List<T> parseArray(final String json, final Class<T> clazz) {
return JSON.parseArray(json, clazz);
}

/**
* <pre>
* 从json字符串中按照路径寻找,并解析出一个对象的集合,例如:
* 类Person有一个属性name,要从以下json中解析出其集合:
* {
* "page_info":{
* "items":{
* "item":[{"name":"KelvinZ"},{"name":"Jobs"},...{"name":"Gates"}]
* }
* }
* 使用方法:parseArray(json, "page_info,items,item", Person.class),
* 将根据指定路径,正确的解析出所需集合,排除外层干扰
*
* @param json json字符串
* @param path 逗号分隔的json层次结构
* @param clazz 目标类
* @return
*/
public static final <T> List<T> parseArray(final String json, final String path, final Class<T> clazz) {
String[] keys = path.split(",");
JSONObject obj = JSON.parseObject(json);
for (int i = 0; i < keys.length - 1; i++) {
obj = obj.getJSONObject(keys[i]);
}
String inner = obj.getString(keys[keys.length - 1]);
List<T> ret = parseArray(inner, clazz);
return ret;
}

/**
* <pre>
* 有些json的常见格式错误这里可以处理,以便给后续的方法处理
* 常见错误:使用了\" 或者 "{ 或者 }",腾讯的页面中常见这种格式
*
* @param invalidJson 包含非法格式的json字符串
* @return
*/
public static final String correctJson(final String invalidJson) {
String content = invalidJson.replace("\\\"", "\"").replace("\"{", "{").replace("}\"", "}");
return content;
}

/**
* 格式化Json
*
* @param json
* @return
*/
public static final String formatJson(String json) {
Map<?, ?> map = (Map<?, ?>) JSON.parse(json);
return JSON.toJSONString(map, true);
}

/**
* 获取json串中的子json
*
* @param json
* @param path
* @return
*/
public static final String getSubJson(String json, String path) {
String[] keys = path.split(",");
JSONObject obj = JSON.parseObject(json);
for (int i = 0; i < keys.length - 1; i++) {
obj = obj.getJSONObject(keys[i]);
System.out.println(obj.toJSONString());
}
return obj != null ? obj.getString(keys[keys.length - 1]) : null;
}

}

文章目录
  1. 1. 【1】准备工作:
  2. 2. 【2】创建url和访问key 以及参数等:
  3. 3. 【3】请求这个第三方接口:
  4. 4. 【4】根据接口返回数据格式来解析数据: