Httpclient的应用

最近项目有用到ssl的httpClient,原项目不支持,所以查资料实现了一下

httpClient官方文档:http://hc.apache.org/

实现参考:https://blog.csdn.net/zhuwukai/article/details/78644484

Http协议的历史演变和设计思想: https://www.oschina.net/news/76365/http-introduce 

采用版本是httpclient4.4.1

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

代码

package com.yao.purchasing.common.util;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import com.alibaba.druid.support.json.JSONUtils;
import com.yao.purchasing.common.enumerate.ReturnCode;
import com.yao.purchasing.common.exception.PmsBizException;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;

import javax.xml.ws.http.HTTPException;

/**
 * 九州通HttpClientJZTT
 * 
 * @author wuqi
 *
 */
public class HttpClientUtilJZT {

    private static Logger logger = Logger.getLogger(HttpClientUtil.class);

    private static PoolingHttpClientConnectionManager connectionManager = null;
    private static HttpClientBuilder httpBuilder = null;
    private static RequestConfig requestConfig = null;
    private static SSLContextBuilder builder = null;
    private static SSLConnectionSocketFactory sslsf = null;
    private static CloseableHttpClient httpClient = null;

    private static int MAXCONNECTION = 100;

    private static int DEFAULTMAXCONNECTION = 20;

    static {
        // 设置http的状态参数
        requestConfig = RequestConfig.custom().setSocketTimeout(15000).setConnectTimeout(15000)
                .setConnectionRequestTimeout(15000).build();

        builder = new SSLContextBuilder();
        // 全部信任 不做SSL身份鉴定
        try {
            builder.loadTrustMaterial(null, new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                    return true;
                }
            });
            sslsf = new SSLConnectionSocketFactory(builder.build(),
                    new String[] { "SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2" }, null, NoopHostnameVerifier.INSTANCE);
            Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                    .register("http", new PlainConnectionSocketFactory()).register("https", sslsf).build();
            connectionManager = new PoolingHttpClientConnectionManager(registry);
            connectionManager.setMaxTotal(MAXCONNECTION);
            connectionManager.setDefaultMaxPerRoute(DEFAULTMAXCONNECTION);
            httpBuilder = HttpClients.custom();
            httpBuilder.setConnectionManager(connectionManager);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }

    }

    // 创建单例httpclient
    public static CloseableHttpClient getConnection() {
        if (httpClient == null) {
            synchronized (HttpClientUtilJZT.class) {
                if (httpClient == null) {
                    httpClient = httpBuilder.setSSLSocketFactory(sslsf).build();
                }
            }
        }
        return httpClient;
    }
    
    public static HttpUriRequest getRequestMethod(Map<String, Object> map, String url, String method, Header header) {
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        Set<Map.Entry<String, Object>> entrySet = map.entrySet();
        for (Map.Entry<String, Object> e : entrySet) {
            String name = e.getKey();
            Object value = e.getValue();
            if (value instanceof String) {
                NameValuePair pair = new BasicNameValuePair(name, (String) value);
                params.add(pair);
            }
            if (value instanceof List) {
                String valueList = JSONUtils.toJSONString(value);
                NameValuePair pair = new BasicNameValuePair(name, valueList);
                params.add(pair);
            }
        }
        HttpUriRequest reqMethod = null;
        if ("post".equals(method)) {
            reqMethod = RequestBuilder.post().setUri(url).addHeader(header)
                    .addParameters(params.toArray(new BasicNameValuePair[params.size()])).setConfig(requestConfig)
                    .build();
        } else if ("get".equals(method)) {
            reqMethod = RequestBuilder.get().setUri(url).addHeader(header)
                    .addParameters(params.toArray(new BasicNameValuePair[params.size()])).setConfig(requestConfig)
                    .build();
        }
        return reqMethod;
    }

    public static String doGet(String url, Map<String, Object> map) throws PmsBizException {
        HttpUriRequest request = getRequestMethod(map, url, "get", null);
        return doExecute(url, request);
    }

    public static String doPost(String url, Map<String, Object> map) throws PmsBizException {
        HttpUriRequest request = getRequestMethod(map, url, "post", null);
        return doExecute(url, request);
    }
    
    public static String doPost(String url, Header header, Map<String, Object> map) throws PmsBizException {
        HttpUriRequest request = getRequestMethod(map, url, "post", header);
        return doExecute(url, request);
    }

    public static String doPost(String url, String jsonStr) throws PmsBizException {
        HttpPost request = new HttpPost(url);
        request.addHeader(HTTP.CONTENT_TYPE, "application/json");
        StringEntity entity = new StringEntity(jsonStr,"utf-8");
        request.setEntity(entity);
        return doExecute(url, request);
    }
      
    public static String doExecute(String url, HttpUriRequest request)
            throws PmsBizException {
        CloseableHttpClient client = getConnection();
        CloseableHttpResponse response = null;
        try {
//            logger.info("request:" + map);
            response = client.execute(request);
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                String responseMsg = EntityUtils.toString(entity, "utf-8");
                logger.info("response:" + responseMsg);
                return responseMsg;
            } else {
                logger.error("response httpCode:" + response.getStatusLine().getStatusCode());
                throw new PmsBizException(ReturnCode.THIRD_API_INVOKE_ERR,
                        EntityUtils.toString(response.getEntity(), "utf-8"));
            }
        } catch (ClientProtocolException e) {
            logger.error("doPost error", e);
        } catch (IOException e) {
            logger.error("doPost error", e);
        } finally {
            if (response != null) {
                try {
                    response.close();// 释放链接
                } catch (IOException e) {
                    logger.error("Httpresponse.close error", e);
                }
            }
        }
        return null;
    }

    public static void main(String args[]) throws IOException {

//         HttpUriRequest request = getCode();
//         HttpUriRequest request = getToken();
//         HttpUriRequest request = getTest();
        HttpUriRequest request = postTest();
        HttpClient client = getConnection();
        HttpResponse response = client.execute(request);

        if (response.getStatusLine().getStatusCode() == 200) {
            HttpEntity entity = response.getEntity();
            String message = EntityUtils.toString(entity, "utf-8");
            System.out.println(message);
        } else {
            System.out.println("请求失败");
            HttpEntity entity = response.getEntity();
            String message = EntityUtils.toString(entity, "utf-8");
            System.out.println(message);
        }
    }
}

httpclient传输的两种方式

API地址:http://hc.apache.org/httpcomponents-core-4.4.x/httpcore/apidocs/index.html

Entity:

BasicHttpEntity:基础的Entity,传输字节流

ByteArrayEntity:传输字节数组的Entity

EntityTemplate:

FileEntity:传输文件的Entity

InputStreamEntity:传输字节流的Entity

SerializableEntity:传输可序列化对象的Entity

StringEntity:传输String字符串的Entity

Enity在Servlet接收时都是用request.getInputSteam()获取,然后实例化成各种相应的Entity;可以看到

    //发送
    HttpPost request = new HttpPost(url);
    request.addHeader(HTTP.CONTENT_TYPE, "application/json");
    StringEntity entity = new StringEntity(jsonStr,"utf-8");
    request.setEntity(entity);
    response = client.execute(request);
    //接受
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain arg2)
            throws IOException, ServletException {
        BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while((line = br.readLine())!=null){
            sb.append(line);
        }
        System.out.println(sb);
    }

Parameters:传输key-value参数

以BasicNameValuePair的数组传输,限制是只支持key-value都为String字符串类型。下面是部分代码,具体看最上面的例子

    //发送
    reqMethod = RequestBuilder.post().setUri(url).addHeader(header)
                    .addParameters(params.toArray(new BasicNameValuePair[params.size()])).setConfig(requestConfig)
                    .build();
response = client.execute(request);
//接受
for(String key:request.getParameterMap().keySet()) {
System.out.println(request.getParameter(key));
}

 两种方式建议用Entity,Parameters限制太大满足不了大部分需求,我原本是用Parameters的,但是后面涉及json嵌套,只有兼容Entity,采用StringEntity实现了

猜你喜欢

转载自www.cnblogs.com/wqff-biubiu/p/9156447.html
今日推荐