package org.common.util.http;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.annotation.PostConstruct;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.ParseException;
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.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
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;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
/**
* http访问客户端 restfull风格
* @author michael
* @date 2023-11-2
*/
@Slf4j
@Component
public class HttpClientUtil {
@Value("${httpclient.out-time}")
private Integer outTime;
// 3.设置请求和传输超时时间
private RequestConfig requestConfig = null;
@PostConstruct
private void initConfig() {
requestConfig = RequestConfig.custom().setConnectionRequestTimeout(15000).setConnectTimeout(outTime).setSocketTimeout(outTime).build();
}
/**
* GET请求
* @param url
* @param params
* @param headParams
* @return
*/
public String doHttpGet(String url, Map<String, Object> params, Map<String, String> headParams) {
return doRequest(RequestMode.GET,url, params, headParams, RequestDataMode.FORM);
}
/**
* DELETE请求
* @param url
* @param params
* @param headParams
* @return
*/
public String doHttpDelete(String url, Map<String, Object> params, Map<String, String> headParams) {
return doRequest(RequestMode.DELETE,url, params, headParams, RequestDataMode.FORM);
}
/**
* post表单提交方法
* @param url
* @param params
* @param headParams
* @return
*/
public String doPostFrom(String url, Map<String, Object> params, Map<String, String> headParams) {
return doRequest(RequestMode.POST,url, params, headParams, RequestDataMode.FORM);
}
/**
* post json请求方式
* @param url 请求地址
* @param params 请求参数
* @param headParams 头部参数
* @return
*/
public String doPostJson(String url, Map<String, Object> params, Map<String, String> headParams) {
return doRequest(RequestMode.POST,url, params, headParams, RequestDataMode.JSON);
}
/**
* put json请求方式
* @param url 请求地址
* @param params 请求参数
* @param headParams 头部参数
* @return
*/
public String doPutJson(String url, Map<String, Object> params, Map<String, String> headParams) {
return doRequest(RequestMode.PUT,url, params, headParams, RequestDataMode.JSON);
}
/**
* put表单提交方法
* @param url
* @param params
* @param headParams
* @return
*/
public String doPutForm(String url, Map<String, Object> params, Map<String, String> headParams) {
return doRequest(RequestMode.PUT,url, params, headParams, RequestDataMode.FORM);
}
/**
* post请求方法
* @param url
* @param params
* @param headParams
* @param dataMode
* @return
*/
private String doRequest(RequestMode mode,String url, Map<String, Object> params, Map<String, String> headParams,RequestDataMode dataMode) {
String result = null;
log.info("{}方式请求{} 发送数据方式[{}]",mode.getValue(),url,dataMode.getValue());
// 1. 获取httpclient对象
CloseableHttpClient httpClient = createHttpClient(url);
CloseableHttpResponse response = null;
try {
HttpRequestBase httpReq = createHttpRequest(mode, url, params, headParams, dataMode);
response = httpClient.execute(httpReq);
// 5.得到响应信息
int statusCode = response.getStatusLine().getStatusCode();
// 6. 判断响应信息是否正确
if (HttpStatus.SC_OK != statusCode) {
// 结束请求并抛出异常
httpReq.abort();
log.error("请求响应失败{}",EntityUtils.toString(response.getEntity(), "UTF-8"));
throw new RuntimeException("HttpClient,error status code :" + statusCode);
}
// 7. 转换成实体类
HttpEntity entity = response.getEntity();
if (null != entity) {
result = EntityUtils.toString(entity, "UTF-8");
}
EntityUtils.consume(entity);
log.info("请求返回结果{}",result);
} catch (Exception e) {
log.error("请求失败",e);
} finally {
// 8. 关闭所有资源连接
closeConnection(httpClient, response);
}
return result;
}
/**
* 设置请求头及配置
* @param headParams 请求头参数
* @param httpReq 请求
*/
private void setHttpConfigAndHeader(Map<String, String> headParams, HttpRequestBase httpReq) {
httpReq.setConfig(this.requestConfig);
/*
* 此处可以添加一些请求头信息,例如: httpGet.addHeader("content-type","text/xml");
*/
if(!CollectionUtils.isEmpty(headParams)) {
for (String head : headParams.keySet()) {
httpReq.addHeader(head, headParams.get(head));
}
}
}
/**
* 创建http请求
* @param mode 请求方式枚举
* @param url 请求地址
* @param params 请求参数
* @param headParams 头部参数
* @param RM 请求数据方式FORM/JSON
* @return
* @throws IOException
* @throws UnsupportedEncodingException
* @throws ParseException
* @throws URISyntaxException
*/
private HttpRequestBase createHttpRequest(RequestMode mode, String url, Map<String, Object> params,Map<String, String> headParams, RequestDataMode RM) throws ParseException, UnsupportedEncodingException, IOException, URISyntaxException {
HttpRequestBase result = null;
log.info("请求参数为:{}",JSON.toJSONString(params));
switch (mode) {
case GET:
URIBuilder uriBuilder = new URIBuilder(url);
if (!CollectionUtils.isEmpty(params)) {
Set<Entry<String, Object>> entrySet = params.entrySet();
for (Entry<String, Object> entry : entrySet) {
uriBuilder.setParameter(entry.getKey(), entry.getValue().toString());
}
}
// 2.创建get请求
HttpGet httpGet = new HttpGet(uriBuilder.build());
setHttpConfigAndHeader(headParams, httpGet);;
result = httpGet;
break;
case POST:
// 2. 创建post请求
HttpPost httpPost = new HttpPost(url);
// 3.设置请求和传输超时时间及请求头
setHttpConfigAndHeader(headParams, httpPost);;
if (!CollectionUtils.isEmpty(params)) {
if(RM.equals(RequestDataMode.FORM)) {
// 4.提交参数发送请求
List<BasicNameValuePair> paramsList1 = new ArrayList<>();
for (String key : params.keySet()) {
paramsList1.add(new BasicNameValuePair(key, params.get(key).toString()));
}
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(paramsList1, Charset.forName("utf-8"));
httpPost.setEntity(urlEncodedFormEntity);
}else if(RM.equals(RequestDataMode.JSON)){
// 4.提交参数发送请求
httpPost.setEntity(new StringEntity(JSON.toJSONString(params), ContentType.create("application/json", "utf-8")));
}
}
result = httpPost;
break;
case PUT:
// 2. 创建put请求
HttpPut httpPut = new HttpPut(url);
// 3.设置请求和传输超时时间及请求头
setHttpConfigAndHeader(headParams, httpPut);;
if (!CollectionUtils.isEmpty(params)) {
if(RM.equals(RequestDataMode.FORM)) {
// 4.提交参数发送请求
List<BasicNameValuePair> paramsList1 = new ArrayList<>();
for (String key : params.keySet()) {
paramsList1.add(new BasicNameValuePair(key, params.get(key).toString()));
}
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(paramsList1, Charset.forName("utf-8"));
httpPut.setEntity(urlEncodedFormEntity);
}else if(RM.equals(RequestDataMode.JSON)){
// 4.提交参数发送请求
httpPut.setEntity(new StringEntity(JSON.toJSONString(params), ContentType.create("application/json", "utf-8")));
}
}
result = httpPut;
break;
case DELETE:
// 2. 创建DELETE请求
StringBuffer sb1 = new StringBuffer(url);
if (!CollectionUtils.isEmpty(params)) {
List<BasicNameValuePair> paramsList1 = new ArrayList<BasicNameValuePair>();
for (String key : params.keySet()) {
paramsList1.add(new BasicNameValuePair(key, params.get(key).toString()));
}
String paramStr1 = EntityUtils.toString(new UrlEncodedFormEntity(paramsList1));
// 拼接参数
sb1.append("?");
sb1.append(paramStr1);
}
HttpDelete httpDelete = new HttpDelete(sb1.toString());
result = httpDelete;
break;
default:
break;
}
return result;
}
/**
* https证书信任
* @return
*/
private TrustManager[] trustManager() {
return new TrustManager[]{new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] arg0,
String arg1) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] arg0,
String arg1) throws CertificateException {
}
}};
}
/**
* 创建http请求,支持http及https
* @return
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
private CloseableHttpClient createHttpClient(String url) {
try {
//获取url请求协议
String httpSchema = url.substring(0, url.indexOf(":"));
//协议为https
if("https".equalsIgnoreCase(httpSchema)) {
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, trustManager(), null);
SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);
return HttpClients.custom().setDefaultRequestConfig(requestConfig).setSSLSocketFactory(ssf).build();
}else {
//协议为http
CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();
return httpClient;
}
}catch (Exception e) {
log.error("创建http链接失败",e);
return null;
}
}
/**
* 关闭资源
* @param httpClient
* @param response
*/
private void closeConnection(CloseableHttpClient httpClient,CloseableHttpResponse response) {
// 8. 关闭所有资源连接
if (null != response) {
try {
response.close();
} catch (IOException e) {
log.error("关闭response资源失败",e);
}
}
if (null != httpClient) {
try {
httpClient.close();
} catch (IOException e) {
log.error("关闭httpclient链接",e);
}
}
}
}
restfull风格HttpClient工具类
于 2023-11-03 15:18:26 首次发布
本文介绍了HttpClientUtil组件,用于在SpringBoot应用中执行RESTful风格的HTTP请求,包括GET、DELETE、POST、PUT方法,支持JSON数据和HTTPS安全连接,通过ApacheHttpClient库实现.
摘要由CSDN通过智能技术生成