HttpClient与Spring的整合

来源:互联网 发布:em算法 统计学方法 编辑:程序博客网 时间:2024/06/06 12:46

本文整合基于httpclient-4.5.2版本。

加入httpclient依赖

<dependency>    <groupId>org.apache.httpcomponents</groupId>    <artifactId>httpclient</artifactId>    <version>4.5.2</version></dependency>

编写Spring与HttpClient整合的配置文件

applicationContext-httpclient.xml

<beans xmlns="http://www.springframework.org/schema/beans"    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">    <bean id="poolingHttpClientConnectionManager"        class="org.apache.http.impl.conn.PoolingHttpClientConnectionManager">        <!-- 最大连接数 -->        <property name="maxTotal" value="${http.maxTotal}" />        <!-- 设置每个主机的并发数 -->        <property name="defaultMaxPerRoute" value="${http.defaultMaxPerRoute}" />    </bean>    <!-- HttpClient对象的构建器 -->    <bean id="httpClientBuilder" class="org.apache.http.impl.client.HttpClientBuilder">        <property name="connectionManager" ref="poolingHttpClientConnectionManager" />    </bean>    <!-- HttpClient对象 注意该对象需要设置scope="prototype":多例 -->    <bean class="org.apache.http.impl.client.CloseableHttpClient"        factory-bean="httpClientBuilder" factory-method="build" scope="prototype" />    <!-- 请求配置的构建器 -->    <bean id="requestConfigBuilder" class="org.apache.http.client.config.RequestConfig.Builder">        <!-- 创建连接的最长时间 -->        <property name="connectTimeout" value="${http.connectTimeout}" />        <!-- 从连接池中获取到连接的最长时间 -->        <property name="connectionRequestTimeout" value="${http.connectionRequestTimeout}" />        <!-- 数据传输的最长时间 -->        <property name="socketTimeout" value="${http.socketTimeout}" />        <!-- 提交请求前测试连接是否可用 -->        <property name="staleConnectionCheckEnabled" value="${http.staleConnectionCheckEnabled}" />    </bean>    <!-- RequestConfig对象 -->    <bean class="org.apache.http.client.config.RequestConfig"        factory-bean="requestConfigBuilder" factory-method="build" />    <!-- 定期清理无效连接 -->    <bean class="com.taotao.web.httpclient.IdleConnectionEvictor">        <constructor-arg index="0" ref="poolingHttpClientConnectionManager"/>    </bean> </beans>

httpclient.properties的配置文件

http.maxTotal=200http.defaultMaxPerRoute=50http.connectTimeout=1000http.connectionRequestTimeout=500http.socketTimeout=10000http.staleConnectionCheckEnabled=true

httpclient封装的工具类

package com.taotao.web.service;import java.io.IOException;import java.net.URISyntaxException;import java.util.ArrayList;import java.util.Map;import org.apache.http.NameValuePair;import org.apache.http.client.ClientProtocolException;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.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.client.utils.URIBuilder;import org.apache.http.entity.ContentType;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.message.BasicNameValuePair;import org.apache.http.util.EntityUtils;import org.springframework.beans.BeansException;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.BeanFactoryAware;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.taotao.web.httpclient.HttpResult;@Servicepublic class ApiService implements BeanFactoryAware {    // @Autowired    // private CloseableHttpClient httpclient;    @Autowired    private RequestConfig requestConfig;    private BeanFactory beanFactory;    /**     * 解决单例对象中使用多例对象的问题     * 如:该类ApiService使用@Service注解默认是单例模式,所有引用对象httpclient只实例化一次,     * 而httpclient需要多例,可参考上面Spring配置中scope="prototype",     * 利用bean工厂手动获取httpclient实例,保证每次都是不同实例。     */    @Override    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {        this.beanFactory = beanFactory;    }    private CloseableHttpClient getHttpClient() {        return this.beanFactory.getBean(CloseableHttpClient.class);    }    /**     * GET请求     *      * @param url     * @return     * @throws ClientProtocolException     * @throws IOException     */    public String doGet(String url) throws ClientProtocolException, IOException {        // 创建http GET请求        HttpGet httpGet = new HttpGet(url);        httpGet.setConfig(this.requestConfig);        CloseableHttpResponse response = null;        try {            // 执行请求            response = getHttpClient().execute(httpGet);            // 判断返回状态是否为200            if (response.getStatusLine().getStatusCode() == 200) {                return EntityUtils.toString(response.getEntity(), "UTF-8");            }        } finally {            if (response != null) {                response.close();            }        }        return null;    }    /**     * GET 请求,带参数     *      * @param url     * @param params     * @return     * @throws ClientProtocolException     * @throws IOException     * @throws URISyntaxException     */    public String doGet(String url, Map<String, String> params)            throws ClientProtocolException, IOException, URISyntaxException {        if (null == params)            return this.doGet(url);        URIBuilder uriBuilder = new URIBuilder();        for (Map.Entry<String, String> entry : params.entrySet()) {            uriBuilder.addParameter(entry.getKey(), entry.getValue());        }        return this.doGet(uriBuilder.build().toString());    }    /**     * POST请求     *      * @param url     * @return     * @throws ClientProtocolException     * @throws IOException     */    public HttpResult doPost(String url) throws ClientProtocolException, IOException {        return doPost(url, null);    }    /**     * POST请求,带参数     *      * @param url     * @return     * @throws ClientProtocolException     * @throws IOException     */    public HttpResult doPost(String url, Map<String, String> params)            throws ClientProtocolException, IOException {        // 创建http POST请求        HttpPost httpPost = new HttpPost(url);        if (null != params) {            ArrayList<NameValuePair> pairs = new ArrayList<NameValuePair>();            for (Map.Entry<String, String> entry : params.entrySet()) {                pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));            }            // 构造一个form表单式的实体            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(pairs);            // 将请求实体设置到httpPost对象中            httpPost.setEntity(entity);        }        httpPost.setConfig(this.requestConfig);        // 伪装成浏览器        httpPost.setHeader("User-Agent",                "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36");        CloseableHttpResponse response = null;        try {            // 执行请求            response = getHttpClient().execute(httpPost);            return new HttpResult(response.getStatusLine().getStatusCode(),                    EntityUtils.toString(response.getEntity(), "UTF-8"));        } finally {            if (response != null) {                response.close();            }        }    }    /**     * POST请求,提交json数据     *      * @param url     * @param json     * @return     * @throws ClientProtocolException     * @throws IOException     */    public HttpResult doPostJson(String url, String json) throws ClientProtocolException, IOException {        // 创建http POST请求        HttpPost httpPost = new HttpPost(url);        httpPost.setConfig(this.requestConfig);        if (json != null) {            // 构造一个form表单式的实体            StringEntity stringEntity = new StringEntity(json, ContentType.APPLICATION_JSON);            // 将请求实体设置到httpPost对象中            httpPost.setEntity(stringEntity);        }        CloseableHttpResponse response = null;        try {            // 执行请求            response = this.getHttpClient().execute(httpPost);            return new HttpResult(response.getStatusLine().getStatusCode(),                    EntityUtils.toString(response.getEntity(), "UTF-8"));        } finally {            if (response != null) {                response.close();            }        }    }}

http执行post请求返回的封装类

package com.taotao.web.httpclient;/** * http执行post请求返回的封装类 * @author huangyk * Created on 2016年12月2日 下午3:38:27 */public class HttpResult {    private Integer code;    private String body;    public HttpResult() {    }    public HttpResult(Integer code, String body) {        this.code = code;        this.body = body;    }    public Integer getCode() {        return code;    }    public void setCode(Integer code) {        this.code = code;    }    public String getBody() {        return body;    }    public void setBody(String body) {        this.body = body;    }}

定期清理无效连接线程

package com.taotao.web.httpclient;import org.apache.http.conn.HttpClientConnectionManager;/** * 定期清理无效连接线程 * @author huangyk * Created on 2016年12月2日 下午3:35:25 */public class IdleConnectionEvictor extends Thread {    private final HttpClientConnectionManager connMgr;    private volatile boolean shutdown;    public IdleConnectionEvictor(HttpClientConnectionManager connMgr) {        this.connMgr = connMgr;        // 自启动        this.start();    }    @Override    public void run() {        try {            while (!shutdown) {                synchronized (this) {                    wait(5000);                    // 关闭失效的连接                    connMgr.closeExpiredConnections();                }            }        } catch (InterruptedException ex) {            // 结束        }    }    public void shutdown() {        shutdown = true;        synchronized (this) {            notifyAll();        }    }}
0 0