一、jar包依赖;
org.apache.httpcomponents httpclient
二、以前在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(); } }
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, Mapmap){ String result=null; //声明httpPost请求 HttpPost httpPost = new HttpPost(url); //加入配置信息 httpPost.setConfig(requestConfig); CloseableHttpResponse httpResponse = null; try { //判断map是否为空,不为空则进行遍历,封装from表单对象 if (map != null) { List list = new ArrayList (); for (Entry 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 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 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 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 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 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 paramMap, String encoding){ String result = null; HttpPost httpPost = new HttpPost(url); List paramList = new ArrayList<>(); Set 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; } }
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; } }
三、属性文件:
####################### The config for sirius ################### sirius.bootstrap.enabled=false #集群名称 #sirius.cluster.name= #sirius缓存信息到SF主机的location #sirius.config.path=/wls/appsystems/spri_demo-sf-stg1/config ####################### The config for sirius ################### ####################### The config for database################### spring.datasource.url=jdbc:postgresql://10.31.225.60:6475/test spring.datasource.username=test spring.datasource.password=123456 spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.max-idle=10 spring.datasource.max-wait=10000 spring.datasource.min-idle=5 spring.datasource.initial-size=5 spring.datasource.type=com.mchange.v2.c3p0.ComboPooledDataSource #mybatis plus 设置 #mybatis-plus.mapper-locations=classpath*:com/demo/projectx/server/mapper/*.xml mybatis.configuration.map-underscore-to-camel-case=true ####################### The config for database################### # eureka eureka.client.region=LangFangStandard eureka.client.availabilityZones.LangFangStandard=ocss-eureka-lfa01 eureka.client.serviceUrl.ocss-eureka-lfa01=http://10.60.98.111:8000/eureka/,http://10.60.98.111:8000/eureka/ #eureka.client.serviceUrl.ocss-eureka-lfa01=http://127.0.0.2:9999/eureka/ eureka.instance.prefer-ip-address=true eureka.instance.instance-id: ${spring.cloud.client.ip-address}:${server.port} eureka.instance.status-page-url=http://${spring.cloud.client.ip-address}:${server.port}/swagger-ui.html # 不同网关下的请求由对方网关转发 framework.feign.gatewaytransfer=false #redisSingle ##单服务器 spring.redis.host=10.59.97.222 spring.redis.port=6000 spring.redis.database=0 ################shiro################s password.algorithmName=md5 password.hashIterations=2 #######################The config for remote################### #本地remote地址 remote.api.url=http://10.119.136.111:8088 #######################The config for remote################### #######################The config for HttpClient################### #最大连接数 http.maxTotal=300 #并发数 http.defaultMaxPerRoute=50 #创建连接的最长时间 http.connectTimeout=1000 #从连接池中获取到连接的最长时间 http.connectionRequestTimeout=500 #数据传输的最长时间 http.socketTimeout=20000 #提交请求前测试连接是否可用 http.staleConnectionCheckEnabled=true #测试环境代理(廊坊):VIP:10.49.162.70:80 http.proxy.hostname=10.49.162.70 http.proxy.port=80 #######################The config for HttpClient###################
相关的类:
import lombok.Builder; import lombok.Data; import java.io.Serializable; /** * */ @Data @Builder public class Resultimplements Serializable { private static final long serialVersionUID = 1L; private String responseCode; private String responseMessage; private T responseData; @SuppressWarnings("rawtypes") private static final Result EMPTY_SUCCESS_RESULT = Result.success(null); @SuppressWarnings("unchecked") public static Result success() { return EMPTY_SUCCESS_RESULT; } public static Result success(T obj) { ResultBuilder resultBuilder = new ResultBuilder (); return resultBuilder.responseData(obj) .responseCode(CommonResultStatus.OK.getCode()) .responseMessage(CommonResultStatus.OK.getMessage()) .build(); } @SuppressWarnings("rawtypes") public static Result failure(ResultStatus resultStatus) { return Result.builder() .responseCode(resultStatus.getCode()) .responseMessage(resultStatus.getMessage()).build(); } @SuppressWarnings("rawtypes") public static Result failure(ResultStatus resultStatus, Throwable e) { return Result.builder() .responseData(e) .responseCode(resultStatus.getCode()) .responseMessage(resultStatus.getMessage()).build(); } @SuppressWarnings("rawtypes") public static Result failure(ResultStatus resultStatus, String message) { return Result.builder() .responseCode(resultStatus.getCode()) .responseMessage(message).build(); } @SuppressWarnings("rawtypes") public static Result failure(String code, String message) { return Result.builder() .responseCode(code) .responseMessage(message).build(); } }