springBoot框架下配置HttpClient远程服务调用

 

一、jar包就用jdk自带的;

二、以前在xml里面需要写的配置,现在都通过注解的方式实现:

  1、配置类

springBoot框架下配置HttpClient远程服务调用
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、组件类

springBoot框架下配置HttpClient远程服务调用
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、服务调用类:

springBoot框架下配置HttpClient远程服务调用
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

 

三、属性文件:

springBoot框架下配置HttpClient远程服务调用
#######################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

 

上一篇:HttpUtil 发送请求


下一篇:HttpClient之post请求