手机版
你好,游客 登录 注册 搜索
背景:
阅读新闻

SpringBoot 整合 HttpClient

[日期:2019-04-30] 来源:Linux社区  作者:super-jing [字体: ]

第一步:引入HttpClient 的jar包

  1、httpClient 5.0 开始支持异步(Async)请求;

  2、httpclient 版本过低上传文件会出,原因是 org.apache.http.entity.ContentType 没有方法 withParameters(final NameValuePair... params);

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>
<!-- httpClient文件上传需要 -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpmime</artifactId>
</dependency>

第二步:创建一个httpClient的配置类

package com.123.lenovo.adapter.se.config;

import Java.security.KeyStore;
import javax.net.ssl.SSLContext;

import org.apache.http.HeaderElement;
import org.apache.http.HeaderElementIterator;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustAllStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContexts;
import org.elasticsearch.Build;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.123.lenovo.adapter.se.common.IdleConnectionEvictor;

@Configuration
public class HttpClientConfig {

    @Value("${http_max_total}")
    private int maxTotal = 800;
   
    @Value("${http_default_max_perRoute}")
    private int defaultMaxPerRoute = 80;
   
    @Value("${http_validate_after_inactivity}")
    private int validateAfterInactivity = 1000;
   
    @Value("${http_connection_request_timeout}")
    private int connectionRequestTimeout = 5000;
   
    @Value("${http_connection_timeout}")
    private int connectTimeout = 10000;
   
    @Value("${http_socket_timeout}")
    private int socketTimeout = 20000;
   
    @Value("${waitTime}")
    private int waitTime = 30000;
   
    @Value("${idleConTime}")
    private int idleConTime = 3;
   
    @Value("${retryCount}")
    private int retryCount = 3;
   
    @Bean
    public PoolingHttpClientConnectionManager createPoolingHttpClientConnectionManager() {
        PoolingHttpClientConnectionManager poolmanager = new PoolingHttpClientConnectionManager();
        poolmanager.setMaxTotal(maxTotal);
        poolmanager.setDefaultMaxPerRoute(defaultMaxPerRoute);
        poolmanager.setValidateAfterInactivity(validateAfterInactivity);
        return poolmanager;
    }
   
    @Bean
    public CloseableHttpClient createHttpClient(PoolingHttpClientConnectionManager poolManager) {
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create().setConnectionManager(poolManager);
        httpClientBuilder.setKeepAliveStrategy(new ConnectionKeepAliveStrategy() {
           
            @Override
            public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
                HeaderElementIterator iterator = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
                while (iterator.hasNext()) {
                    HeaderElement headerElement = iterator.nextElement();
                    String param = headerElement.getName();
                    String value = headerElement.getValue();
                    if (null != value && param.equalsIgnoreCase("timeout")) {
                        return Long.parseLong(value) * 1000;
                    }
                }
                return 30 * 1000;
            }
        });
        httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(retryCount, false));
        return httpClientBuilder.build();
    }102   
    @Bean
    public RequestConfig createRequestConfig() {
        return RequestConfig.custom()
                .setConnectionRequestTimeout(connectionRequestTimeout)    // 从连接池中取连接的超时时间
                .setConnectTimeout(connectTimeout)                        // 连接超时时间
                .setSocketTimeout(socketTimeout)                        // 请求超时时间
                .build();
    }
   
    @Bean
    public IdleConnectionEvictor createIdleConnectionEvictor(PoolingHttpClientConnectionManager poolManager) {
        IdleConnectionEvictor idleConnectionEvictor = new IdleConnectionEvictor(poolManager, waitTime, idleConTime);
        return idleConnectionEvictor;
    }
   
}

第三步:创建httpClient的工具类

@Component
public class HttpClientHelper {
   
    private Logger LOGGER = LoggerFactory.getLogger(HttpClientHelper.class);
   
    @Autowired
    private CloseableHttpClient httpClient;
   
    @Autowired
    private RequestConfig requestConfig;
   
    public String get(String url, HashMap<String, Object> paramMap, HashMap<String, Object> header) {
        String result = null;
        if ("".equals(url)) {
            return result;
        }
        // 创建一个request对象
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = null;
        try {
            // 配置连接参数
            httpGet.setConfig(requestConfig);
            //设置参数 
            if (paramMap != null && paramMap.size() > 0) {
                List<NameValuePair> params = new ArrayList<>();
                for (Entry<String, Object> entry : paramMap.entrySet()) {
                    params.add(new BasicNameValuePair(entry.getKey(), URLEncoder.encode(entry.getValue().toString(), "UTF-8")));
                }
                String strParams = EntityUtils.toString(new UrlEncodedFormEntity(params));
                // 防止多参数时,分隔符","被转义
                String realParams = URLDecoder.decode(strParams, "UTF-8");
                httpGet.setURI(new URI(httpGet.getURI().toString().indexOf("?") > 0 ? httpGet.getURI().toString() + "&" + realParams : httpGet.getURI().toString() + "?" + realParams));
            }
            // 设置头
            if (header != null && header.size() > 0) {
                for (Entry<String, Object> entry : header.entrySet()) {
                    httpGet.addHeader(entry.getKey(), entry.getValue().toString());
                }
            }
            // 执行request请求
            response = httpClient.execute(httpGet);
            result = parseResponse(response);
           
        } catch (Exception e) {
            LOGGER.error("url : "+ url +", msg : " + e.getMessage());
            httpGet.abort();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
   
    public String post(String url, HashMap<String, Object> paramMap, HashMap<String, Object> header) {
        String result = null;
        if ("".equals(url)) {
            return result;
        }
        // 创建一个request对象
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpResponse response = null;
        try {
            // 配置连接参数
            httpPost.setConfig(requestConfig);
            // 设置参数
            if (paramMap != null && paramMap.size() > 0) {
                List<NameValuePair> params = new ArrayList<>();
                for (Entry<String, Object> entry : paramMap.entrySet()) {
                    params.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
                }
                HttpEntity entity = new UrlEncodedFormEntity(params);
                httpPost.setEntity(entity);
            }
            // 设置头
            if (header != null && header.size() > 0) {
                for (Entry<String, Object> entry : header.entrySet()) {
                    httpPost.addHeader(entry.getKey(), entry.getValue().toString());
                }
            }
            // 执行request请求
            response = httpClient.execute(httpPost);
            result = reponseHandle(response);
        } catch (Exception e) {
            LOGGER.error("url : "+ url +", msg : " + e.getMessage());
            httpPost.abort();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
   
    public String postJSON(String url, String json_str, HashMap<String, Object> header) {
        String result = null;
        if ("".equals(url)) {
            return result;
        }
        // 创建一个request对象
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpResponse response = null;
        try {
            // 配置连接参数
            httpPost.setConfig(requestConfig);
            // 设置参数
            if (json_str != null && !"".equals(json_str)) {
                StringEntity entity = new StringEntity(json_str, 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请求
            response = httpClient.execute(httpPost);
            result = reponseHandle(response);
           
        } catch (Exception e) {
            LOGGER.error("url : "+ url +", msg : " + e.getMessage()+", param : " +json_str);
            httpPost.abort();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
   
    public String uploadFile(String url, String filePath, String fileParam, Map<String, Object> params) {
        File file = new File(filePath);
        if (!(file.exists() && file.isFile())) {
            throw new RuntimeException("file : file is null");
        }
        String result = null;
        if ("".equals(url)) {
            return result;
        }
        // 创建一个request对象
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpResponse response = null;
        try {
            // 配置连接参数
            httpPost.setConfig(requestConfig);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            builder.addBinaryBody(fileParam, file, ContentType.DEFAULT_BINARY, file.getName());
            if (params != null && params.size() > 0) {
                for (Entry<String, Object> entry : params.entrySet()) {
                    builder.addTextBody(entry.getKey(), entry.getValue().toString(), ContentType.create("text/plain", Consts.UTF_8));
                }
            }
            HttpEntity requestEntity = builder.build();
            httpPost.setEntity(requestEntity);
            // 执行request请求
            response = httpClient.execute(httpPost);
            result = reponseHandle(response);
           
        } catch (Exception e) {
            httpPost.abort();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
   
    /**
    * 解析 response数据
    * @description
    * @param response
    * @return
    * @author tangjingjing
    * @date 2018年10月12日
    */
    private String parseResponse(CloseableHttpResponse response) {
        String result = "";
        // 获取响应体
        HttpEntity httpEntity = null;
        InputStream inputStream = null;
        try {
            // 获取响应状态
            int statusCode = response.getStatusLine().getStatusCode();
            // 没有正常响应
            if (statusCode < HttpStatus.SC_OK || statusCode >= HttpStatus.SC_MULTIPLE_CHOICES) {
                throw new RuntimeException("statusCode : " + statusCode);
            }
            // 获取响应体
            httpEntity = response.getEntity();
            if (httpEntity != null) {
                inputStream = httpEntity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
                StringBuffer sb = new StringBuffer();
                String line = "";
                while((line=reader.readLine())!=null){
                    sb.append(line);
                }
                reader.close();
                result = sb.toString();
            }

        } catch (Exception e) {
            LOGGER.error("HttpClientHelper parseResponse error", e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 如果httpEntity没有被完全消耗,那么连接无法安全重复使用,将被关闭并丢弃
            try {
                EntityUtils.consume(httpEntity);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
   
    private String reponseHandle(CloseableHttpResponse response) {
        String result = "";
        // 获取响应体
        HttpEntity httpEntity = null;
        try {
            // 获取响应状态
            int statusCode = response.getStatusLine().getStatusCode();
            // 没有正常响应
            if (statusCode < HttpStatus.SC_OK || statusCode >= HttpStatus.SC_MULTIPLE_CHOICES) {
                throw new RuntimeException("statusCode : " + statusCode);
            }
            // 获取响应体
            httpEntity = response.getEntity();
            if (httpEntity !=null) {
                result = EntityUtils.toString(httpEntity);
            }
           
        } catch (Exception e) {
            LOGGER.error("HttpClientHelper reponseHandle error", e);
        } finally {
            // 如果httpEntity没有被完全消耗,那么连接无法安全重复使用,将被关闭并丢弃
            try {
                EntityUtils.consume(httpEntity);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
   
}

第四步:创建HttpClient无效连接清除类

/**
 * 定期清理无效的http连接
 * @author viruser
 *
 */
package com.123.lenovo.adapter.se.common;

import java.util.concurrent.TimeUnit;

import javax.annotation.PreDestroy;

import org.apache.http.conn.HttpClientConnectionManager;

/**
 * 定期清理无效的http连接
 * @author viruser
 *
 */
public class IdleConnectionEvictor extends Thread {

    private final HttpClientConnectionManager manager;
   
    private Integer waitTime;
   
    private Integer idleConTime;
   
    private volatile boolean shutdown = true;
   
    public IdleConnectionEvictor(HttpClientConnectionManager manager, Integer waitTime, Integer idleConTime) {
        this.manager = manager;
        this.waitTime = waitTime;
        this.idleConTime = idleConTime;
        this.start();
    }
   
    @Override
    public void run() {
        try {
            if (shutdown) {
                synchronized (this) {
                    wait(waitTime);
                    manager.closeIdleConnections(idleConTime, TimeUnit.SECONDS);
                    // 关闭失效的连接
                    manager.closeExpiredConnections();
                }
            }
        } catch (Exception e) {
           
        }
    }
   
    @PreDestroy
    public void shutdown() {
        shutdown = false;
        synchronized (this) {
            notifyAll();
        }
    }
   
}

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址https://www.linuxidc.com/Linux/2019-04/158400.htm

linux
相关资讯       HttpClient  SpringBoot 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款