spring集成httpclient配置

原文地址

原 spring集成httpclient配置
wcyong wcyong
发布时间: 2016/03/12 21:39 阅读: 1712 收藏: 29 点赞: 5 评论: 4

摘要
spring httpclient
HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。

spring与httpclient集成方式如下:

引入jar包

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

2.编写执行get和post请求的java类

package com.wee.common.service;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
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.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.wee.common.bean.HttpResult;

@Service
public class HttpClientService {

    @Autowired
    private CloseableHttpClient httpClient;
    @Autowired
    private RequestConfig requestConfig;

    /**
     * 执行GET请求
     * 
     * @param url
     * @return
     * @throws IOException
     * @throws ClientProtocolException
     */
    public String doGet(String url) throws ClientProtocolException, IOException {
        // 创建http GET请求
        HttpGet httpGet = new HttpGet(url);
        httpGet.setConfig(this.requestConfig);

        CloseableHttpResponse response = null;
        try {
            // 执行请求
            response = httpClient.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 URISyntaxException
     * @throws IOException
     * @throws ClientProtocolException
     */
    public String doGet(String url, Map<String, String> params)
            throws ClientProtocolException, IOException, URISyntaxException {
        URIBuilder uriBuilder = new URIBuilder(url);
        for (String key : params.keySet()) {
            uriBuilder.addParameter(key, params.get(key));
        }
        return this.doGet(uriBuilder.build().toString());
    }

    /**
     * 执行POST请求
     * 
     * @param url
     * @param params
     * @return
     * @throws IOException
     */
    public HttpResult doPost(String url, Map<String, String> params) throws IOException {
        // 创建http POST请求
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(this.requestConfig);
        if (params != null) {
            // 设置2个post参数,一个是scope、一个是q
            List<NameValuePair> parameters = new ArrayList<NameValuePair>();
            for (String key : params.keySet()) {
                parameters.add(new BasicNameValuePair(key, params.get(key)));
            }
            // 构造一个form表单式的实体
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
            // 将请求实体设置到httpPost对象中
            httpPost.setEntity(formEntity);
        }

        CloseableHttpResponse response = null;
        try {
            // 执行请求
            response = httpClient.execute(httpPost);
            return new HttpResult(response.getStatusLine().getStatusCode(),
                    EntityUtils.toString(response.getEntity(), "UTF-8"));
        } finally {
            if (response != null) {
                response.close();
            }
        }
    }

    /**
     * 执行POST请求
     * 
     * @param url
     * @return
     * @throws IOException
     */
    public HttpResult doPost(String url) throws IOException {
        return this.doPost(url, null);
    }

    /**
     * 提交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.httpClient.execute(httpPost);
            return new HttpResult(response.getStatusLine().getStatusCode(),
                    EntityUtils.toString(response.getEntity(), "UTF-8"));
        } finally {
            if (response != null) {
                response.close();
            }
        }
    }

}
    HttpResult.java

public class HttpResult {

    /**
     * 状态码
     */
    private Integer status;
    /**
     * 返回数据
     */
    private String data;

    public HttpResult() {
    }

    public HttpResult(Integer status, String data) {
        this.status = status;
        this.data = data;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

}

3.spring和httpClient整合配置文件

<!-- 定义连接管理器 -->
    <bean id="httpClientConnectionManager"
        class="org.apache.http.impl.conn.PoolingHttpClientConnectionManager"
        destroy-method="close">
        <!-- 最大连接数 -->
        <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="httpClientConnectionManager" />
    </bean>

    <!-- 定义Httpclient对象 -->
    <bean id="httpClient" class="org.apache.http.impl.client.CloseableHttpClient"
        factory-bean="httpClientBuilder" factory-method="build" scope="prototype">
    </bean>

    <!-- 定义清理无效连接 -->
    <bean class="com.taotao.common.httpclient.IdleConnectionEvictor"
        destroy-method="shutdown">
        <constructor-arg index="0" ref="httpClientConnectionManager" />
    </bean>

    <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>
    <!-- 定义请求参数 -->
    <bean id="requestConfig" class="org.apache.http.client.config.RequestConfig" factory-bean="requestConfigBuilder" factory-method="build">
    </bean>

4.httpclient.properties

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

5.使用一个单独的线程完成连接池中的无效链接的清理

package com.wee.common.httpclient;

import org.apache.http.conn.HttpClientConnectionManager;

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();
        }
    }
}
posted @ 2016-09-14 15:19  A_yes  阅读(713)  评论(1编辑  收藏  举报