zoukankan      html  css  js  c++  java
  • 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实现了

  • 相关阅读:
    其实 Linux IO 模型没那么难
    七年三次大重构,聊聊我的重构成长史
    听说 JVM 性能优化很难?今天我小试了一把!
    盘点三年来写过的原创文章
    如何快速实现一个连接池?
    树结构系列(四):MongoDb 使用的到底是 B 树,还是 B+ 树?
    树结构系列(三):B树、B+树
    树结构系列(二):平衡二叉树、AVL树、红黑树
    树结构系列(一):从普通树到二叉查找树
    静态代码分析工具清单
  • 原文地址:https://www.cnblogs.com/wqff-biubiu/p/9156447.html
Copyright © 2011-2022 走看看