一、jar包就用jdk自带的;
二、以前在xml里面需要写的配置,现在都通过注解的方式实现:
1、配置类
import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * HttpClient的配置类 */ @Slf4j @Configuration public class HttpClientConfig { @Value("${http.maxTotal}") private Integer maxTotal; @Value("${http.defaultMaxPerRoute}") private Integer defaultMaxPerRoute; @Value("${http.connectTimeout}") private Integer connectTimeout; @Value("${http.connectionRequestTimeout}") private Integer connectionRequestTimeout; @Value("${http.socketTimeout}") private Integer socketTimeout; /**代理-hostname*/ @Value("${http.proxy.hostname}") private String proxyHostname; /**代理-端口*/ @Value("${http.proxy.port}") private Integer proxyPort; /**定义httpClient连接池*/ @Bean(name = "httpClientConnectionManager") public PoolingHttpClientConnectionManager getHttpClientConnectionManager() { log.info("maxTotal:{},defaultMaxPerRoute:{}",maxTotal,defaultMaxPerRoute); PoolingHttpClientConnectionManager httpClientConnectionManager = new PoolingHttpClientConnectionManager(); //最大连接数 httpClientConnectionManager.setMaxTotal(maxTotal); //并发数 httpClientConnectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute); return httpClientConnectionManager; } /** * 定义 HttpClient工厂,这里使用HttpClientBuilder构建 * 实例化连接池,设置连接池管理器。 * 以参数形式注入上面实例化的连接池管理器 */ @Bean(name = "httpClientBuilder") public HttpClientBuilder getHttpClientBuilder(@Qualifier("httpClientConnectionManager") PoolingHttpClientConnectionManager httpClientConnectionManager) { //HttpClientBuilder中的构造方法被protected修饰, // 所以这里不能直接使用new来实例化一个HttpClientBuilder, // 可以使用HttpClientBuilder提供的静态方法create()来获取HttpClientBuilder对象 HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); httpClientBuilder.setConnectionManager(httpClientConnectionManager); return httpClientBuilder; } /** * 注入连接池,用于获取httpClient */ @Bean public CloseableHttpClient getCloseableHttpClient(@Qualifier("httpClientBuilder") HttpClientBuilder httpClientBuilder) { return httpClientBuilder.build(); } /** * 定义requestConfig的工厂 * Builder是RequestConfig的一个内部类 * 通过RequestConfig的custom方法来获取到一个Builder对象 * 设置builder的连接信息 * 这里还可以设置proxy,cookieSpec等属性。有需要的话可以在此设置 * @return */ @Bean(name = "builder") public RequestConfig.Builder getBuilder() { return RequestConfig.custom() .setConnectTimeout(connectTimeout) .setConnectionRequestTimeout(connectionRequestTimeout) .setSocketTimeout(socketTimeout); } @Bean(name = "proxyBuilder") public RequestConfig.Builder getBuilderWithProxy() { return RequestConfig.custom() .setProxy(new HttpHost(proxyHostname, proxyPort)) .setConnectTimeout(connectTimeout) .setConnectionRequestTimeout(connectionRequestTimeout) .setSocketTimeout(socketTimeout); } /** * 使用builder构建一个RequestConfig对象 */ @Bean(name = "requestConfig") public RequestConfig getRequestConfig(@Qualifier("builder") RequestConfig.Builder builder) { return builder.build(); } @Bean(name = "proxyRequestConfig") public RequestConfig getProxyRequestConfig(@Qualifier("proxyBuilder") RequestConfig.Builder builder) { return builder.build(); } }HttpClientConfig.java
2、组件类
import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.StatusLine; 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.HttpPost; 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.ssl.SSLContextBuilder; import org.apache.http.ssl.TrustStrategy; import org.apache.http.util.EntityUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import javax.net.ssl.SSLContext; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.*; import java.util.Map.Entry; @Slf4j @Component public class HttpClientHelper { @Autowired(required=false) private CloseableHttpClient httpClient; @Autowired @Qualifier("requestConfig") private RequestConfig requestConfig; @Autowired @Qualifier("proxyRequestConfig") private RequestConfig proxyRequestConfig; /**带参数的post请求 */ public String doPost(String url, Map<String, Object> map){ String result=null; //声明httpPost请求 HttpPost httpPost = new HttpPost(url); //加入配置信息 httpPost.setConfig(requestConfig); CloseableHttpResponse httpResponse = null; try { //判断map是否为空,不为空则进行遍历,封装from表单对象 if (map != null) { List<NameValuePair> list = new ArrayList<NameValuePair>(); for (Entry<String, Object> entry : map.entrySet()) { list.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString())); } //构造from表单对象 UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(list, "UTF-8"); //把表单放到post里 httpPost.setEntity(urlEncodedFormEntity); } //发起请求 httpResponse = this.httpClient.execute(httpPost); //判断是否成功 if(httpResponse.getStatusLine().getStatusCode()==200){ result= EntityUtils.toString(httpResponse.getEntity(),"UTF-8"); } }catch (Exception e) { log.error("HttpClientHelper.doPost-url : "+ url +", msg : " + e.getMessage()); httpPost.abort(); }finally { try { if (httpResponse != null) { httpResponse.close(); } } catch (IOException e) { e.printStackTrace(); } } return result; } public String doPostJsonWithProxy(String url,String jsonStr) { return doPostJSON(url,jsonStr,null,true); } public String doPostWithProxy(String url,String jsonStr,HashMap<String, Object> header) { return doPostJSON(url,jsonStr,header,true); } public String doPostSSLJsonWithProxy(String url,String jsonStr) { return doPostSSLJSON(url,jsonStr,null,true); } public String doPostJSON(String url,String jsonStr) { return doPostJSON(url,jsonStr,null,false); } public String doPostJSON(String url,String jsonStr,HashMap<String, Object> header,boolean withProxy) { String result = null; //创建一个request对象 HttpPost httpPost = new HttpPost(url); //配置连接参数 if(withProxy){ log.info("使用代理访问"); httpPost.setConfig(proxyRequestConfig); }else { httpPost.setConfig(requestConfig); } CloseableHttpResponse httpResponse = null; try { //设置参数 if (jsonStr != null && !"".equals(jsonStr)) { StringEntity entity = new StringEntity(jsonStr, ContentType.APPLICATION_JSON); entity.setContentEncoding("UTF-8"); entity.setContentType("application/json"); httpPost.setEntity(entity); } //设置头 if (header != null && header.size() > 0) { for (Entry<String, Object> entry : header.entrySet()) { httpPost.addHeader(entry.getKey(), entry.getValue().toString()); } } //执行request请求 httpResponse = httpClient.execute(httpPost); log.info("code="+httpResponse.getStatusLine().getStatusCode()); //判断是否成功 if(httpResponse.getStatusLine().getStatusCode()==200){ result= EntityUtils.toString(httpResponse.getEntity(),"UTF-8"); } } catch (Exception e) { log.error("HttpClientHelper.doPostJSON-url : "+ url +", msg : " + e.getMessage()); httpPost.abort(); } finally { try { if (httpResponse != null) { httpResponse.close(); } } catch (IOException e) { e.printStackTrace(); } } return result; } public String doPostSSLJSON(String url,String jsonStr,HashMap<String, Object> header,boolean withProxy) { String result = null; //创建一个request对象 HttpPost httpPost = new HttpPost(url); //配置连接参数 if(withProxy){ log.info("使用代理访问"); httpPost.setConfig(proxyRequestConfig); }else { httpPost.setConfig(requestConfig); } CloseableHttpResponse httpResponse = null; CloseableHttpClient cHttpClient = null; try { //没有用连接池!!! cHttpClient = createSSLClientDefault(); } catch (Exception e1) { e1.printStackTrace(); } try { //设置参数 if (jsonStr != null && !"".equals(jsonStr)) { StringEntity entity = new StringEntity(jsonStr, ContentType.APPLICATION_JSON); entity.setContentEncoding("UTF-8"); entity.setContentType("application/json"); httpPost.setEntity(entity); } //设置头 if (header != null && header.size() > 0) { for (Entry<String, Object> entry : header.entrySet()) { httpPost.addHeader(entry.getKey(), entry.getValue().toString()); } } log.info("httpPost="+httpPost.getConfig().toString()); //执行request请求 httpResponse = cHttpClient.execute(httpPost); log.info("code="+httpResponse.getStatusLine().getStatusCode()); //判断是否成功 if(httpResponse.getStatusLine().getStatusCode()==200){ result= EntityUtils.toString(httpResponse.getEntity(),"UTF-8"); } } catch (Exception e) { log.error("HttpClientHelper.doPostJSON-url : "+ url +", msg : " + e.getMessage()); httpPost.abort(); } finally { try { if (httpResponse != null) { httpResponse.close(); } } catch (IOException e) { e.printStackTrace(); } } return result; } public static CloseableHttpClient createSSLClientDefault() throws Exception{ SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy(){ //信任所有 public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { return true; } }).build(); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext); return HttpClients.custom().setSSLSocketFactory(sslsf).build(); } /** * 发送httpPost 表单提交 * @return */ public String doPost(String url, Map<String,Object> paramMap, String encoding){ String result = null; HttpPost httpPost = new HttpPost(url); List<NameValuePair> paramList = new ArrayList<>(); Set<String> keySet = paramMap.keySet(); NameValuePair pair = null; for(String key:keySet){ pair = new BasicNameValuePair(key, paramMap.get(key).toString()); paramList.add(pair); } CloseableHttpResponse response = null; HttpEntity entity = null; try { httpPost.setConfig(proxyRequestConfig); httpPost.setEntity(new UrlEncodedFormEntity(paramList,encoding)); httpPost.setHeader("charset","UTF-8"); httpPost.setHeader("Content-Type","application/x-www-form-urlencoded"); long startTime = System.currentTimeMillis(); log.info("[HttpClient Post] begin invoke, url:{},params:{}",url,paramList); response = httpClient.execute(httpPost); long callTime = System.currentTimeMillis() - startTime; log.info("[HttpClient Post] end invoke used :"+callTime/1000+" second"); entity = response.getEntity(); // 获取响应实体 //打印状态日志 StatusLine status = response.getStatusLine(); if(status!=null){ log.info("[HttpClient Post] return status:"+status.getStatusCode()); } if (null != entity && status.getStatusCode() == 200) { result = EntityUtils.toString(entity, encoding); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (Exception e1){ e1.printStackTrace(); } finally { if(entity != null){ try { entity.getContent().close(); } catch (Exception e) { log.error("entity.getContent().close() error",e); } } if(response != null){ try { response.close(); } catch (IOException e) { log.error("response.close() error",e); } } httpPost.releaseConnection(); } return result; } }HttpClientHelper.java
3、服务调用类:
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.demo.common.Result; import com.demo.common.consts.Constant; import com.demo.common.enums.MessageEnum; import com.demo.common.util.StringUtil; import com.demo.exception.BusinessException; import com.demo.remote.HttpClientHelper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.Map; @Slf4j @Service public class RemoteApiSao{ @Autowired private HttpClientHelper httpClientHelper; public Result send(String requestUrl, Object params) { log.info("------请求-url:{},最终报文---------------:{}",requestUrl,JSON.toJSONString(params)); String response = httpClientHelper.doPostJSON(requestUrl, JSON.toJSONString(params)); log.info("------响应-原始报文---------------:{}",response); Result res = this.packageResponse(response); return res; } /** * 响应报文处理 * @param response * @return */ private Result packageResponse(String response) { if(StringUtil.isEmpty(response)) { throw new BusinessException(MessageEnum.RemoteResponseIsNull); } Result result = JSON.parseObject(response,Result.class); return result; } }RemoteApiSao.java
三、属性文件:
#######################The config for HttpClient################### #最大连接数 http.maxTotal=300 #并发数 http.defaultMaxPerRoute=50 #创建连接的最长时间 http.connectTimeout=1000 #从连接池中获取到连接的最长时间 http.connectionRequestTimeout=500 #数据传输的最长时间 http.socketTimeout=20000 #提交请求前测试连接是否可用 http.staleConnectionCheckEnabled=true #测试环境代理:VIP:10.11.112.60:80 http.proxy.hostname=10.11.112.60 http.proxy.port=80 #######################The config for HttpClient###################application-dev.properties