springBoot框架下配置HttpClient遠程服務調用


 

一、jar包依賴;

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>
View Code

 

二、以前在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  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###################
application-dev.properties

 

 

 

相關的類:

import lombok.Builder;
import lombok.Data;
import java.io.Serializable;

/**
 * 
 */
@Data
@Builder
public class Result<T> implements 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 <T> Result<T> success() {
        return EMPTY_SUCCESS_RESULT;
    }

    public static <T> Result<T> success(T obj) {
        ResultBuilder<T> resultBuilder = new ResultBuilder<T>();
        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();
       }

}
Result.java

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM