1 pom.xml
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.11</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
2 转接http接口
package com.sb.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.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.apache.http.Consts;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
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.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.HttpStatus;
import net.sf.json.JSONObject;
public class HttpClientUtil {
public static String doGet(String url, Map<String, String> param, Map<String, String> headers) {
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
//设置请求超时时间(各项超时参数具体含义链接)
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(10000)
.setConnectionRequestTimeout(10000)
.setSocketTimeout(10000)
.build();
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);
//给这个请求设置请求配置
httpGet.setConfig(requestConfig);
httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2");
if(headers != null){
for(String headerKey:headers.keySet()){
httpGet.addHeader(headerKey, headers.get(headerKey));
}
}
// 执行请求
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;
}
/*
*Post请求,传参为Map
*/
public static String doPost(String url, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
//设置请求超时时间
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(10000)
.setConnectionRequestTimeout(10000)
.setSocketTimeout(10000)
.build();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
httpPost.setConfig(requestConfig);
// 创建参数列表
if (param != null) {
List<NameValuePair> paramList = new ArrayList<NameValuePair>();
for (String key : param.keySet()) {
paramList.add(new BasicNameValuePair(key, param.get(key)));
System.out.format("param list:"+paramList+"\n");
}
// 模拟表单
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
httpPost.setEntity(entity);
}
// 执行http请求
response = httpClient.execute(httpPost);
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return resultString;
}
/*
*Post请求,传参为json字符串
*/
public static String doPostJson(String url, String json) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
//设置请求超时时间
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(10000)
.setConnectionRequestTimeout(10000)
.setSocketTimeout(10000)
.build();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
httpPost.setConfig(requestConfig);
// 创建请求内容 ,发送json数据需要设置contentType
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
System.out.format("entity:"+entity+"\n");
// httpPost.addHeader("Content-Type", "application/json");
httpPost.setEntity(entity);
// 执行http请求
response = httpClient.execute(httpPost);
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return resultString;
}
}
3 转接https接口
3.1 跳过认证
package com.sb.util.https;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
public class HttpsTrustClientV45 extends HttpsClientV45 {
public HttpsTrustClientV45() {
}
@Override
public void prepareCertificate() throws Exception {
// 跳过证书验证
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
// 设置成已信任的证书
ctx.init(null, new TrustManager[] { tm }, null);
this.connectionSocketFactory = new SSLConnectionSocketFactory(ctx);
}
}
3.2 使用证书
package com.sb.util.https;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import javax.net.ssl.SSLContext;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.ssl.SSLContexts;
public class HttpsCertifiedClientV45 extends HttpsClientV45{
public HttpsCertifiedClientV45(){}
@Override
public void prepareCertificate() throws Exception{
// 获取密钥库
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStream inputStream = new FileInputStream(new File("classpath:**.keystore"));
try{
trustStore.load(inputStream, "password".toCharArray());
}finally{
inputStream.close();
}
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(trustStore, TrustSelfSignedStrategy.INSTANCE)
.build();
this.connectionSocketFactory = new SSLConnectionSocketFactory(sslContext);
}
}
- 异常
javax.net.ssl.SSLPeerUnverifiedException: Certificate for <218.17.121.227> doesn’t match any of the subject alternative names: [172.168.1.20] - 解决方案
this.connectionSocketFactory = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);
3.3 认证注册
package com.sb.util.https;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
public abstract class HttpsClientV45 extends HttpClientBuilder {
private CloseableHttpClient client;
protected ConnectionSocketFactory connectionSocketFactory;
/**
* 初始化HTTPSClient
*
* @return 返回当前实例
* @throws Exception
*/
public CloseableHttpClient init() throws Exception {
this.prepareCertificate();
this.regist();
return this.client;
}
/**
* 准备证书验证
*
* @throws Exception
*/
public abstract void prepareCertificate() throws Exception;
/**
* 注册协议和端口, 此方法也可以被子类重写
*/
protected void regist() {
// 设置协议http和https对应的处理socket链接工厂的对象
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", this.connectionSocketFactory)
.build();
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
HttpClients.custom().setConnectionManager(connManager);
// 创建自定义的httpclient对象
this.client = HttpClients.custom().setConnectionManager(connManager).build();
// CloseableHttpClient client = HttpClients.createDefault();
}
}
3.4 请求方法
Get请求,参数不多的情况下可以在URL中直接拼接,传入doGet中;
Post请求,解析Body有两种方式,通过String解析,通过Map解析;
package com.sb.util.https;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Iterator;
import java.util.Arrays;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.Header;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.ContentType;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.http.entity.StringEntity;
public class HttpsClientV45Util {
/**
* Post请求,外部setBody解析Body
* @param httpClient
* @param url
* @param paramHeader
* @param paramBody
* @return
* @throws Exception
*/
public static String doPost(HttpClient httpClient, String url, Map<String, String> paramHeader,
Map<String, String> paramBody) throws Exception {
String result = null;
HttpPost httpPost = new HttpPost(url);
setHeader(httpPost, paramHeader);
setBody(httpPost, paramBody, "UTF-8");
HttpResponse response = httpClient.execute(httpPost);
if (response != null) {
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
result = EntityUtils.toString(resEntity, "UTF-8");
}
}
return result;
}
/**
* Post请求,内置解析Body
* @param httpClient
* @param url
* @param paramHeader
* @param paramBody
* @return
* @throws Exception
*/
public static String doPostString(HttpClient httpClient, String url, Map<String, String> paramHeader,
String paramBody) throws Exception {
String result = null;
HttpPost httpPost = new HttpPost(url);
setHeader(httpPost, paramHeader);
StringEntity entity = new StringEntity(paramBody, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost);
if (response != null) {
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
result = EntityUtils.toString(resEntity, "UTF-8");
}
}
return result;
}
public static String doPostGetHeader(HttpClient httpClient, String url, Map<String, String> paramHeader,
String paramBody) throws Exception {
String result = null;
HttpPost httpPost = new HttpPost(url);
setHeader(httpPost, paramHeader);
StringEntity entity = new StringEntity(paramBody, ContentType.APPLICATION_JSON);
System.out.format("entity:"+entity+"\n");
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost);
// System.out.format("all headers"+response.getAllHeaders()+"\n");
// System.out.format("all headers"+response.getAllHeaders()+"\n");
Header[] headersAll = response.getAllHeaders();
// for(Header header:headersAll){
// System.out.format("header all value:"+header.getValue()+"\n");
// }
Header[] headersPart = response.getHeaders("X-Subject-Token");
String resultHeader = headersPart[0].getValue();
return resultHeader;
// for(Header header:headersPart){
// System.out.format("header part:"+header.getValue()+"\n");
// }
// if (response != null) {
// HttpEntity resEntity = response.getEntity();
// if (resEntity != null) {
// result = EntityUtils.toString(resEntity, "UTF-8");
// }
// }
// return result;
}
public static String doGet(HttpClient httpClient, String url, Map<String, String> paramHeader,
Map<String, String> paramBody) throws Exception {
# url为拼接后的完整路径
String result = null;
HttpGet httpGet = new HttpGet(url);
setHeader(httpGet, paramHeader);
HttpResponse response = httpClient.execute(httpGet);
if (response != null) {
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
result = EntityUtils.toString(resEntity, "UTF-8");
}
}
return result;
}
private static void setHeader(HttpRequestBase request, Map<String, String> paramHeader) {
// 设置Header
if (paramHeader != null) {
Set<String> keySet = paramHeader.keySet();
for (String key : keySet) {
request.addHeader(key, paramHeader.get(key));
}
}
}
private static void setBody(HttpPost httpPost, Map<String, String> paramBody, String charset) throws Exception {
// 设置参数
if (paramBody != null) {
System.out.format("param body: "+paramBody+"\n");
List<NameValuePair> list = new ArrayList<NameValuePair>();
Set<String> keySet = paramBody.keySet();
for (String key : keySet) {
list.add(new BasicNameValuePair(key, paramBody.get(key)));
}
if (list.size() > 0) {
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, charset);
httpPost.setEntity(entity);
}
}
}
}
4 测试
package com.sb.controller;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import com.sb.util.HttpClientUtil;
import com.sb.util.https.HttpsClientV45Util;
import com.sb.util.https.HttpsTrustClientV45;
import net.sf.json.JSONObject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.apache.http.client.HttpClient;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RestController;
import org.apache.http.client.HttpClient;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@CrossOrigin(origins="*", maxAge=3600)
@RestController
@RequestMapping("/api")
public class CallAPIController{
@RequestMapping(value="/call/test-get", method=RequestMethod.POST)
public Map testGet(@RequestBody Map infos){
if(infos.containsKey("name") && infos.containsKey("sex")){
String url = "http://127.0.0.1:8091/test-get";
String str = HttpClientUtil.doGet(url, infos, null);
Map outInfos = (Map)JSONObject.fromObject(str);
return outInfos;
}else{
Map errorMap = new HashMap(){
{
put("code", 400);
put("infos","请检查输入参数");
}
};
return errorMap;
}
}
@RequestMapping(value="/call/test-post", method=RequestMethod.POST)
public Map testPost(@RequestBody Map infos){
if(infos.containsKey("name")&&infos.containsKey("sex")){
String url="http://127.0.0.1:8091/test-json";
// string json
String param = JSONObject.fromObject(infos).toString();
String str = HttpClientUtil.doPostJson(url, param);
Map outInfos = (Map)JSONObject.fromObject(str);
return outInfos;
}else{
Map errorMap = new HashMap(){
{
put("code", 400);
put("infos", "输入参数有误,请检查输入参数");
}
};
return errorMap;
}
}
@RequestMapping(value="/call/token-get", method=RequestMethod.POST)
public Map getToken(@RequestBody Map params, HttpServletRequest req){
Map<String, String> paramHeader = new HashMap<String, String>();
paramHeader.put("Accept", "application/json");
String url = "https://****";
String strJson = JSONObject.fromObject(params).toString();
String result = null;
System.out.format("str json:"+strJson+"\n");
HttpClient httpClient = null;
try{
httpClient = new HttpsTrustClientV45().init();
result = HttpsClientV45Util.doPostGetHeader(httpClient, url, paramHeader, strJson);
// System.out.format("result:"+result+"\n");
}catch(Exception e){
e.printStackTrace();
}
Map token = new HashMap();
token.put("code", 200);
token.put("token", result);
return token;
}
}
【参考文献】
[1]https://www.jb51.net/article/134997.htm
[2]https://blog.csdn.net/Xin_101/article/details/99542841
[3]https://blog.csdn.net/gnail_oug/article/details/80324120
[4]https://blog.csdn.net/Breezeg/article/details/100934849
[5]https://www.cnblogs.com/stonefeng/p/10429716.html