zoukankan      html  css  js  c++  java
  • HttpClient

    本文主要大致介绍HttpClient(基于HttpClient 4.5)及如何使用,附HttpUtil工具类。

     一、HttpClient使用流程

      1、创建HttpClient对象

      2、创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。

      3、如果需要发送请求参数,可调用HttpGetsetParams方法来添加请求参数;对于HttpPost对象而言,可调用setEntity(HttpEntity entity)方法来设置请求参数。

      4、调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse对象。

      5、调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。

      6、释放连接。无论执行方法是否成功,都必须释放连接

      二、介绍

      1、GET,HEAD, POST, PUT, DELETE, TRACE and OPTIONS.对应的HttpClient中的类型分别为HttpGet,HttpHead, HttpPost, HttpPut, HttpDelete, HttpTrace, and HttpOptions.

      2、响应头,设置和获取响应头:

            HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
            response.addHeader("Set-Cookie", "c1=a; path=/; domain=localhost");
            response.addHeader("Set-Cookie", "c2=b; path="/", c3=c; domain="localhost"");
            HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator("Set-Cookie"));
            while (it.hasNext()) {
                HeaderElement elem = it.nextElement();
                System.out.println(elem.getName() + " = " + elem.getValue());
                NameValuePair[] params = elem.getParameters();
                for (int i = 0; i < params.length; i++) {
                    System.out.println(" " + params[i]);
                }
            }

      3、HTTP entity

      HTTP消息可以携带与请求或响应相关联的内容实体(entity)。对应请求报文中的请求主体和响应报文中的响应正文。

    请求报文构成 请求报文由请求行(请求方式,URI和HTTP版本),请求头空行(CR+LF,回车符+换行符),请求数据主体构成。
    响应报文构成 响应报文由状态行(HTTP版本,状态码,原因),响应头空行响应正文构成。


      根据内容的来源,HttpClient区分了三种实体:

        1)streamed:内容以流的方式接收

        2)self-contained:内容在内存中,或者通过独立于连接或其他实体的方式获取。self-contained实体通常是可重复的。这种类型的实体将主要用于封装HTTP请求的实体。

        3)wrapping:内容是从另一个实体获得的

      可重复的实体:意思是它的内容可以读取一次或多次,仅存在于self-contained实体类型,如ByteArrayEntity or StringEntity

       API:

        HttpEntity#getContent() 返回java.io.InputStream

        HttpEntity#getContentType()、HttpEntity#getContentType() 获取响应的Content-Type、Content-Length响应头。

      4、确保释放资源

        httpClient、response及获取的流式的内容等都需要在finally块中进行close。

      5、获取返回内容

        推荐的使用实体内容的方法是使用它的HttpEntity#getContent()或HttpEntity#writeTo(OutputStream)方法。HttpClient还提供了EntityUtils类,它公开了几个静态方法,以便更容易地从实体中读取内容或信息。而不是读java.io。通过使用这个类中的方法,可以直接在astring / byte数组中检索整个内容体。但是,强烈建议不要使用EntityUtils,除非响应实体来自受信任的HTTP服务器,并且已知其长度有限。

            ...
            // http客户端
            CloseableHttpClient httpclient = HttpClients.createDefault();
            // get请求
            HttpGet httpget = new HttpGet(url);
            CloseableHttpResponse response = null;
            try {
                response = httpclient.execute(httpget);
                HttpEntity entity = response.getEntity();
                String content;
                if (entity != null) {
                    long len = entity.getContentLength();
                    if (len != -1 && len < 2048) {
                        content = EntityUtils.toString(entity);
                    } else {
                        // Stream content out
                        InputStream instream = entity.getContent();
                        try {
                            BufferedReader br = new BufferedReader(new InputStreamReader(instream, "UTF-8"));
                            char[] buffer = new char[4096];
                            int length;
                            StringBuilder sb = new StringBuilder();
                            while ((length = br.read(buffer)) > 0) {
                                sb.append(new String(buffer, 0, length));
                            }
                            content = sb.toString();
                        } finally {
                            instream.close();
                        }
                    }
                    resultMap.put("content", content);
                }
            }
    ...            

      在一些情况下需要从entity中多次读取content,这时entity content需要缓存在内存或磁盘中。最简单方法是使用BufferedHttpEntity类包装原始实体,将原始实体的内容读入到内存缓冲区。

        HttpEntity entity = response.getEntity();
                if (entity != null) {
                    entity=new BufferedHttpEntity(entity);
        }

      6、写入entity content

        HttpClient提供了几个类,可用于通过HTTP连接高效地传输内容。这些类的实例可以与封装请求(如POST和PUT)的实体相关联,以便将实体内容封装到传出HTTP请求中。HttpClient为最常见的数据容器提供了几个类,比如字符串、字节数组、输入流和文件:StringEntity、ByteArrayEntity、InputStreamEntity和FileEntity。

       1)HTML forms

        对应的Content-Type:application/x-www-form-urlencoded 

    List<NameValuePair> formparams = new ArrayList<NameValuePair>();
    formparams.add(new BasicNameValuePair("param1", "value1"));
    formparams.add(new BasicNameValuePair("param2", "value2"));
    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
    HttpPost httppost = new HttpPost("http://localhost/handler.do");
    httppost.setEntity(entity);

        UrlEncodedFormEntity实例将使用所谓的URL编码来对参数和进行编码:param1=value1&param2=value2

       2)Content chunking (内容分块)

         对应的Content-Type:application/octet-stream?(不确定)

        用在服务器生成的消息无法确定消息大小,而进行分块加载

    StringEntity entity = new StringEntity("important message",
    ContentType.create("plain/text", Consts.UTF_8));
    entity.setChunked(true);
    HttpPost httppost = new HttpPost("http://localhost/acrtion.do");
    httppost.setEntity(entity);

      7、重试处理器

     HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {
                @Override
                public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
                    if (executionCount >= 5) {
                        // Do not retry if over max retry count
                        return false;
                    }
                    return false;
                }
    
            };
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setRetryHandler(myRetryHandler)
                    .build();

      8、SSL/TLS

        HttpClient利用SSLConnectionSocketFactory来创建SSL连接。SSLConnectionSocketFactory允许高度定制。它可以将javax.net.ssl.SSLContext的实例作为参数,并使用它创建自定义配置的SSL连接

    KeyStore myTrustStore = <...>
    SSLContext sslContext = SSLContexts.custom()
        .loadTrustMaterial(myTrustStore)
        .build();
    SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
    CloseableHttpClient httpclient = HttpClients.custom()
                    .setSSLSocketFactory(sslsf)
                    .build();

      9、Hostname verification

        除了在SSL/TLS协议级别上执行的信任验证和客户端身份验证之外,一旦建立了连接,HttpClient还可以选择性地验证目标主机名是否与存储在服务器的X.509证书中的名称相匹配。这种验证可以为服务器信任材料的真实性提供额外的保证。hostnameverifier接口代表了一种验证主机名的策略。

        重要提示:不应将hostnameverification与SSL信任验证混淆。

        HttpClient附带两个javax.net.ssl.HostnameVerifier实现。

        1)DefaultHostnameVerifier:主机名必须与证书指定的任何替代名称匹配,如果没有替代名称,则提供证书主体的最特定CN

        2)NoopHostnameVerifier:这个主机名验证器实际上关闭了主机名验证。它接受任何有效的、与目标主机匹配的SSL会话。

        每个默认的HttpClient使用DefaultHostnameVerifier实现。如果需要,可以指定不同的主机名验证器实现,如使用NoopHostnameVerifier:

    SSLContext sslContext = SSLContexts.createSystemDefault();
    SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
        sslContext,
        NoopHostnameVerifier.INSTANCE);

       10、HTTP execution context 执行上下文

        最初,HTTP被设计成一种无状态的、面向响应请求的协议。然而,现实世界中的应用程序通常需要能够通过几个逻辑相关的请求-响应交换来持久化状态信息。为了使应用程序能够维护一个处理状态,HttpClient允许在一个特定的执行上下文中执行HTTP请求,即HTTP上下文。如果在连续的请求之间重用相同的上下文,则多个逻辑相关的请求可以参与逻辑会话。HTTP上下文的功能类似于java.util.Map。它只是一个任意命名值的集合。应用程序可以在请求执行之前填充上下文属性,或者在执行完成后检查上下文。

        HttpContext:可能包含任意对象,因此在多个线程之间共享是不安全的。建议每个执行线程维护自己的上下文。

        在HTTP请求执行过程中,HttpClient将以下属性添加到执行上下文

    HttpConnection 实例表示到目标服务器的实际连接
    HttpHost 表示连接目标的实例
    HttpRoute 表示完整连接路由的实例
    HttpRequest 实例表示实际的HTTP请求。执行上下文中的最后一个HttpRequest对象始终表示消息发送到目标服务器时的状态。对于默认的HTTP/1.0和HTTP/1.1,使用相对请求uri。但是,如果以非隧道模式通过代理发送请求,则URI将是绝对的。
    HttpResponse 实例表示实际的HTTP响应
    RequestConfig 表示实际请求配置的对象。
       

       示例:

      

    CloseableHttpClient httpclient = HttpClients.createDefault();
            try {
                // Create a local instance of cookie store
                CookieStore cookieStore = new BasicCookieStore();
    
                // Create local HTTP context
                HttpClientContext localContext = HttpClientContext.create();
                // Bind custom cookie store to the local context
                localContext.setCookieStore(cookieStore);
    
                HttpGet httpget = new HttpGet("http://httpbin.org/cookies");
                System.out.println("Executing request " + httpget.getRequestLine());
    
                // Pass local context as a parameter
                CloseableHttpResponse response = httpclient.execute(httpget, localContext);
                try {
                    System.out.println("----------------------------------------");
                    System.out.println(response.getStatusLine());
                    List<Cookie> cookies = cookieStore.getCookies();
                    for (int i = 0; i < cookies.size(); i++) {
                        System.out.println("Local cookie: " + cookies.get(i));
                    }
                    EntityUtils.consume(response.getEntity());
                } finally {
                    response.close();
                }
            } finally {
                httpclient.close();
            }

      11、设置超时时间

                // 设置超时时间
                RequestConfig requestConfig = RequestConfig.custom()
                        .setSocketTimeout(5000)
                        .setConnectTimeout(5000)
                        .setConnectionRequestTimeout(5000)
                        .build();
                httpPost.setConfig(requestConfig);    

       12、中止请求:httpget.abort();

       13、验证用户身份的请求

     CredentialsProvider credsProvider = new BasicCredentialsProvider();
            credsProvider.setCredentials(
                    new AuthScope("httpbin.org", 80),
                    new UsernamePasswordCredentials("user", "passwd"));
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setDefaultCredentialsProvider(credsProvider)
                    .build();
        ...

      14、设置代理

                HttpHost target = new HttpHost("httpbin.org", 443, "https");// 目标请求地址
                HttpHost proxy = new HttpHost("127.0.0.1", 8080, "http");// 客户端代理
                RequestConfig config = RequestConfig.custom()
                        .setProxy(proxy)
                        .build();
                HttpGet request = new HttpGet("/");
                request.setConfig(config);
                CloseableHttpResponse response = httpclient.execute(target, request);    

      15、通过身份验证代理在安全连接隧道上执行HTTP请求

    CredentialsProvider credsProvider = new BasicCredentialsProvider();
            credsProvider.setCredentials(
                    new AuthScope("localhost", 8888),
                    new UsernamePasswordCredentials("squid", "squid"));
            credsProvider.setCredentials(
                    new AuthScope("httpbin.org", 80),
                    new UsernamePasswordCredentials("user", "passwd"));
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setDefaultCredentialsProvider(credsProvider).build();
            try {
                HttpHost target = new HttpHost("httpbin.org", 80, "http");
                HttpHost proxy = new HttpHost("localhost", 8888);
                RequestConfig config = RequestConfig.custom()
                    .setProxy(proxy)
                    .build();
                HttpGet httpget = new HttpGet("/basic-auth/user/passwd");
                httpget.setConfig(config);
                CloseableHttpResponse response = httpclient.execute(target, httpget);
                try {
                    System.out.println(EntityUtils.toString(response.getEntity()));
                } finally {
                    response.close();
                }
            } finally {
                httpclient.close();
            }

      16、使用块编码(chunk)来发送请求实体

            CloseableHttpClient httpclient = HttpClients.createDefault();
            try {
                HttpPost httppost = new HttpPost("http://httpbin.org/post");
    
                File file = new File("filePath");
    
                InputStreamEntity reqEntity = new InputStreamEntity(
                        new FileInputStream(file), -1, ContentType.APPLICATION_OCTET_STREAM);
                reqEntity.setChunked(true);
                // It may be more appropriate to use FileEntity class in this particular
                // instance but we are using a more generic InputStreamEntity to demonstrate
                // the capability to stream out data from any arbitrary source
                //
                // FileEntity entity = new FileEntity(file, "binary/octet-stream");
    
                httppost.setEntity(reqEntity);
    
                System.out.println("Executing request: " + httppost.getRequestLine());
                CloseableHttpResponse response = httpclient.execute(httppost);
                try {
                    System.out.println(response.getStatusLine());
                    System.out.println(EntityUtils.toString(response.getEntity()));
                } finally {
                    response.close();
                }
            } finally {
                httpclient.close();
            }

      17、使用HttpClient执行基于表单的登录

    BasicCookieStore cookieStore = new BasicCookieStore();
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setDefaultCookieStore(cookieStore)
                    .build();
            try {
                HttpGet httpget = new HttpGet("https://someportal/");
                CloseableHttpResponse response1 = httpclient.execute(httpget);
                try {
                    HttpEntity entity = response1.getEntity();
    
                    System.out.println("Login form get: " + response1.getStatusLine());
                    EntityUtils.consume(entity);
    
                    System.out.println("Initial set of cookies:");
                    List<Cookie> cookies = cookieStore.getCookies();
                    if (cookies.isEmpty()) {
                        System.out.println("None");
                    } else {
                        for (int i = 0; i < cookies.size(); i++) {
                            System.out.println("- " + cookies.get(i).toString());
                        }
                    }
                } finally {
                    response1.close();
                }
    
                HttpUriRequest login = RequestBuilder.post()
                        .setUri(new URI("https://someportal/"))
                        .addParameter("IDToken1", "username")
                        .addParameter("IDToken2", "password")
                        .build();
                CloseableHttpResponse response2 = httpclient.execute(login);
                try {
                    HttpEntity entity = response2.getEntity();
    
                    System.out.println("Login form get: " + response2.getStatusLine());
                    EntityUtils.consume(entity);
    
                    System.out.println("Post logon cookies:");
                    List<Cookie> cookies = cookieStore.getCookies();
                    if (cookies.isEmpty()) {
                        System.out.println("None");
                    } else {
                        for (int i = 0; i < cookies.size(); i++) {
                            System.out.println("- " + cookies.get(i).toString());
                        }
                    }
                } finally {
                    response2.close();
                }
            } finally {
                httpclient.close();
            }

      18、多个工作线程执行HTTP请求

    // Create an HttpClient with the ThreadSafeClientConnManager.
            // This connection manager must be used if more than one thread will
            // be using the HttpClient.
            PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
            cm.setMaxTotal(100);
    
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setConnectionManager(cm)
                    .build();
            try {
                // create an array of URIs to perform GETs on
                String[] urisToGet = {
                    "http://hc.apache.org/",
                    "http://hc.apache.org/httpcomponents-core-ga/",
                    "http://hc.apache.org/httpcomponents-client-ga/",
                };
    
                // create a thread for each URI
                GetThread[] threads = new GetThread[urisToGet.length];
                for (int i = 0; i < threads.length; i++) {
                    HttpGet httpget = new HttpGet(urisToGet[i]);
                    threads[i] = new GetThread(httpclient, httpget, i + 1);
                }
                // start the threads
                for (int j = 0; j < threads.length; j++) {
                    threads[j].start();
                }
                // join the threads
                for (int j = 0; j < threads.length; j++) {
                    threads[j].join();
                }
            } finally {
                httpclient.close();
            }
    
      /**
         * A thread that performs a GET.
         */
        static class GetThread extends Thread {
    
            private final CloseableHttpClient httpClient;
            private final HttpContext context;
            private final HttpGet httpget;
            private final int id;
    
            public GetThread(CloseableHttpClient httpClient, HttpGet httpget, int id) {
                this.httpClient = httpClient;
                this.context = new BasicHttpContext();
                this.httpget = httpget;
                this.id = id;
            }
            /**
             * Executes the GetMethod and prints some status information.
             */
            @Override
            public void run() {
                try {
                    System.out.println(id + " - about to get something from " + httpget.getURI());
                    CloseableHttpResponse response = httpClient.execute(httpget, context);
                    try {
                        System.out.println(id + " - get executed");
                        // get the response body as an array of bytes
                        HttpEntity entity = response.getEntity();
                        if (entity != null) {
                            byte[] bytes = EntityUtils.toByteArray(entity);
                            System.out.println(id + " - " + bytes.length + " bytes read");
                        }
                    } finally {
                        response.close();
                    }
                } catch (Exception e) {
                    System.out.println(id + " - error: " + e);
                }
            }
        }

       19、执行包含多部分编码实体的请求

                HttpPost httppost = new HttpPost("http://localhost:8080" +
                        "/servlets-examples/servlet/RequestInfoExample");
    
                FileBody bin = new FileBody(new File("filePath"));
                StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN);
    
                HttpEntity reqEntity = MultipartEntityBuilder.create()
                        .addPart("bin", bin)
                        .addPart("comment", comment)
                        .build();
                httppost.setEntity(reqEntity);    

      三、使用:

      1、jar包依赖

            <!--httpClient-->
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>4.5.9</version>
            </dependency>

      2、HttpClientUtil工具类

    import org.apache.http.HttpEntity;
    import org.apache.http.NameValuePair;
    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.conn.ssl.NoopHostnameVerifier;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.conn.ssl.TrustStrategy;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.message.BasicNameValuePair;
    import org.apache.http.ssl.SSLContexts;
    import org.apache.http.util.EntityUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import javax.net.ssl.SSLContext;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    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.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * Http工具类
     *
     * @author yangyongjie
     * @date 2020/3/26
     * @desc
     */
    public class HttpClientUtil {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientUtil.class);
    
        /**
         * http get 请求
         *
         * @param url
         * @return
         */
        public static Map<String, Object> doGet(String url) {
            HashMap<String, Object> resultMap = new HashMap<String, Object>(8);
            resultMap.put("isOk", "ok");
            // http客户端
            CloseableHttpClient httpclient = HttpClients.createDefault();
            // get请求
            HttpGet httpget = new HttpGet(url);
            CloseableHttpResponse response = null;
            try {
                response = httpclient.execute(httpget);
                HttpEntity entity = response.getEntity();
                String content;
                if (entity != null) {
                    long len = entity.getContentLength();
                    if (len != -1 && len < 2048) {
                        content = EntityUtils.toString(entity);
                    } else {
                        // Stream content out
                        InputStream instream = entity.getContent();
                        try {
                            BufferedReader br = new BufferedReader(new InputStreamReader(instream, StandardCharsets.UTF_8));
                            char[] buffer = new char[4096];
                            int length;
                            StringBuilder sb = new StringBuilder();
                            while ((length = br.read(buffer)) > 0) {
                                sb.append(new String(buffer, 0, length));
                            }
                            content = sb.toString();
                        } finally {
                            instream.close();
                        }
                    }
                    resultMap.put("content", content);
                }
            } catch (IOException e) {
                LOGGER.error("关闭response异常" + e.getMessage(), e);
            } finally {
                if (response != null) {
                    try {
                        response.close();
                    } catch (IOException e) {
                        LOGGER.error("关闭response异常" + e.getMessage(), e);
                    }
                }
                try {
                    httpclient.close();
                } catch (IOException e) {
                    LOGGER.error("httpclient close exceprion:" + e.getMessage(), e);
                }
            }
            return resultMap;
        }
    
        /**
         * http post 请求
         *
         * @param url
         * @param param
         * @return
         */
        public static Map<String, Object> doPost(String url, Map<String, String> param) {
            HashMap<String, Object> resultMap = new HashMap<String, Object>(8);
            resultMap.put("isOk", "ok");
            CloseableHttpClient httpclient = HttpClients.custom().build();
            try {
                HttpPost httpPost = new HttpPost(url);
                // 设置超时时间
                RequestConfig requestConfig = RequestConfig.custom()
                        .setSocketTimeout(5000)
                        .setConnectTimeout(5000)
                        .setConnectionRequestTimeout(5000)
                        .build();
                httpPost.setConfig(requestConfig);
    
                LOGGER.info("Executing request {}", httpPost.getRequestLine());
                List<NameValuePair> nvps = new ArrayList<NameValuePair>();
                if (param != null) {
                    for (Map.Entry<String, String> entry : param.entrySet()) {
                        nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                    }
                    httpPost.setEntity(new UrlEncodedFormEntity(nvps));
                }
                httpPost.addHeader("Accept-Encoding", "gzip,deflate");
                CloseableHttpResponse response = httpclient.execute(httpPost);
                try {
                    HttpEntity entity = response.getEntity();
                    LOGGER.info("response statusLine:{}", response.getStatusLine());
                    resultMap.put("status", response.getStatusLine().getStatusCode());
                    String content = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
                    resultMap.put("content", content);
                    LOGGER.info("CONTENT={}", content);
                    // and ensure it is fully consumed
                    EntityUtils.consume(entity);
                } finally {
                    response.close();
                }
            } catch (Exception e) {
                LOGGER.error(url + "request exception:" + e.getMessage(), e);
                resultMap.put("isOk", "no");
                return resultMap;
            } finally {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    LOGGER.error("httpclient close exceprion:" + e.getMessage(), e);
                }
            }
            return resultMap;
        }
    
        /**
         * 忽略证书验证的https post请求
         *
         * @param url
         * @param param
         * @return
         */
        public static Map<String, Object> doSSLPost(String url, Map<String, String> param) {
            HashMap<String, Object> resultMap = new HashMap<String, Object>(8);
            resultMap.put("isOk", "ok");
    
            CloseableHttpClient httpclient;
            // Trust own CA and all self-signed certs
            SSLContext sslcontext = null;
            try {
                sslcontext = SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() {
                    // 忽略所有证书验证
                    @Override
                    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                        return true;
                    }
                }).build();
            } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) {
                LOGGER.error("sslcontext error" + e.getMessage(), e);
                resultMap.put("isOk", "no");
                return resultMap;
            }
            // 忽略主机名验证
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, NoopHostnameVerifier.INSTANCE);
            httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
            try {
                HttpPost httpPost = new HttpPost(url);
                // 设置超时时间
                RequestConfig requestConfig = RequestConfig.custom()
                        .setSocketTimeout(5000)
                        .setConnectTimeout(5000)
                        .setConnectionRequestTimeout(5000)
                        .build();
                httpPost.setConfig(requestConfig);
    
                LOGGER.info("Executing request {}", httpPost.getRequestLine());
                List<NameValuePair> nvps = new ArrayList<NameValuePair>();
                if (param != null) {
                    for (Map.Entry<String, String> entry : param.entrySet()) {
                        nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                    }
                    httpPost.setEntity(new UrlEncodedFormEntity(nvps));
                }
                httpPost.addHeader("Accept-Encoding", "gzip,deflate");
                CloseableHttpResponse response = httpclient.execute(httpPost);
                try {
                    HttpEntity entity = response.getEntity();
                    LOGGER.info("response statusLine:{}", response.getStatusLine());
                    resultMap.put("status", response.getStatusLine().getStatusCode());
                    String content = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
                    resultMap.put("content", content);
                    LOGGER.info("CONTENT={}", content);
                    // and ensure it is fully consumed
                    EntityUtils.consume(entity);
                } finally {
                    response.close();
                }
            } catch (Exception e) {
                LOGGER.error(url + "request exception:" + e.getMessage(), e);
                resultMap.put("isOk", "no");
                return resultMap;
            } finally {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    LOGGER.error("httpclient close exceprion:" + e.getMessage(), e);
                }
            }
            return resultMap;
        }
        
    }

     2

    package com.yang.http;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.ResponseHandler;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.slf4j.MDC;
    
    import java.io.IOException;
    import java.nio.charset.Charset;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;
    
    /**
     * 〈一句话功能简述〉
     * 〈功能详细描述〉
     *
     * @author 17090889
     * @see [相关类/方法](可选)
     * @since [产品/模块版本] (可选)
     */
    public class HttpClientTemplate {
        private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientTemplate.class);
    
        private static HttpClient httpClient;
    
        static {
            httpClient = HttpClients.createDefault();
        }
    
        /**
         * 执行get请求
         *
         * @param uri
         * @return
         */
        public static Map<String, Object> executeGet(String uri) {
            HttpGet httpGet = new HttpGet(uri);
            Map<String, Object> resultMap = new HashMap<String, Object>(4);
            try {
                resultMap = httpClient.execute(httpGet, new ResponseHandler<Map<String, Object>>() {
                    public Map<String, Object> handleResponse(HttpResponse httpResponse) throws ClientProtocolException, IOException {
                        HttpEntity httpEntity = httpResponse.getEntity();
                        String result = EntityUtils.toString(httpEntity, Charset.forName("utf-8"));
                        return JSON.parseObject(result);
                    }
                });
            } catch (Exception e) {
                LOGGER.error("执行get请求异常" + e.getMessage(), e);
                return null;
            }
            return resultMap;
        }
    
        /**
         * 执行post请求
         *
         * @param uri
         * @return
         */
        public static Map<String, Object> executePost(String uri, JSONObject jsonObject) {
            HttpPost httpPost = new HttpPost(uri);
            StringEntity entity = new StringEntity(jsonObject.toString(), "utf-8");
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            Map<String, Object> resultMap = new HashMap<String, Object>(4);
            try {
                resultMap = httpClient.execute(httpPost, new ResponseHandler<Map<String, Object>>() {
                    public Map<String, Object> handleResponse(HttpResponse httpResponse) throws ClientProtocolException, IOException {
                        HttpEntity httpEntity = httpResponse.getEntity();
                        String result = EntityUtils.toString(httpEntity, Charset.forName("utf-8"));
                        return JSON.parseObject(result);
                    }
                });
            } catch (IOException e) {
                LOGGER.error("执行post请求异常" + e.getMessage(), e);
                return null;
            }
            return resultMap;
        }
    
        public static void main(String[] args) {
            MDC.put("threadId", UUID.randomUUID().toString().replaceAll("-", ""));
            // 没有数据再调用接口查询
            String uri = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" + "&appId=" + "wxe0e11acdb6dbccbb" + "&secret=" + "7dfb67f45b79292e3b0b969b2590a06b";
            Map<String, Object> resultMap = HttpClientTemplate.executeGet(uri);
            LOGGER.info("getAccessToken-resultMap={}", resultMap);
            String errcode = String.valueOf(resultMap.get("errcode"));
            String accessToken = String.valueOf(resultMap.get("access_token"));
            String expiresIn = String.valueOf(resultMap.get("expires_in"));
    
            // 写死一个行业,其他,41
    
            if (accessToken == null) {
                return;
            }
            String uri2 = "https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token=" + accessToken;
            JSONObject jsonObject = new JSONObject(4);
            jsonObject.put("industry_id1", 1);
            jsonObject.put("industry_id2", "41");
            Map<String, Object> resultMap2 = HttpClientTemplate.executePost(uri2, jsonObject);
            String errcode2 = String.valueOf(resultMap2.get("errcode"));
            MDC.remove("threadId");
        }
    }

      四、官方示例

    /*
     * ====================================================================
     * Licensed to the Apache Software Foundation (ASF) under one
     * or more contributor license agreements.  See the NOTICE file
     * distributed with this work for additional information
     * regarding copyright ownership.  The ASF licenses this file
     * to you under the Apache License, Version 2.0 (the
     * "License"); you may not use this file except in compliance
     * with the License.  You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing,
     * software distributed under the License is distributed on an
     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     * KIND, either express or implied.  See the License for the
     * specific language governing permissions and limitations
     * under the License.
     * ====================================================================
     *
     * This software consists of voluntary contributions made by many
     * individuals on behalf of the Apache Software Foundation.  For more
     * information on the Apache Software Foundation, please see
     * <http://www.apache.org/>.
     *
     */
    
    package org.apache.http.examples.client;
    
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    import java.nio.charset.CodingErrorAction;
    import java.util.Arrays;
    
    import javax.net.ssl.SSLContext;
    
    import org.apache.http.Consts;
    import org.apache.http.Header;
    import org.apache.http.HttpHost;
    import org.apache.http.HttpRequest;
    import org.apache.http.HttpResponse;
    import org.apache.http.ParseException;
    import org.apache.http.client.CookieStore;
    import org.apache.http.client.CredentialsProvider;
    import org.apache.http.client.config.AuthSchemes;
    import org.apache.http.client.config.CookieSpecs;
    import org.apache.http.client.config.RequestConfig;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.protocol.HttpClientContext;
    import org.apache.http.config.ConnectionConfig;
    import org.apache.http.config.MessageConstraints;
    import org.apache.http.config.Registry;
    import org.apache.http.config.RegistryBuilder;
    import org.apache.http.config.SocketConfig;
    import org.apache.http.conn.DnsResolver;
    import org.apache.http.conn.HttpConnectionFactory;
    import org.apache.http.conn.ManagedHttpClientConnection;
    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.SSLConnectionSocketFactory;
    import org.apache.http.impl.DefaultHttpResponseFactory;
    import org.apache.http.impl.client.BasicCookieStore;
    import org.apache.http.impl.client.BasicCredentialsProvider;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.impl.conn.DefaultHttpResponseParser;
    import org.apache.http.impl.conn.DefaultHttpResponseParserFactory;
    import org.apache.http.impl.conn.ManagedHttpClientConnectionFactory;
    import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
    import org.apache.http.impl.conn.SystemDefaultDnsResolver;
    import org.apache.http.impl.io.DefaultHttpRequestWriterFactory;
    import org.apache.http.io.HttpMessageParser;
    import org.apache.http.io.HttpMessageParserFactory;
    import org.apache.http.io.HttpMessageWriterFactory;
    import org.apache.http.io.SessionInputBuffer;
    import org.apache.http.message.BasicHeader;
    import org.apache.http.message.BasicLineParser;
    import org.apache.http.message.LineParser;
    import org.apache.http.ssl.SSLContexts;
    import org.apache.http.util.CharArrayBuffer;
    import org.apache.http.util.EntityUtils;
    
    /**
     * This example demonstrates how to customize and configure the most common aspects
     * of HTTP request execution and connection management.
     */
    public class ClientConfiguration {
    
        public final static void main(String[] args) throws Exception {
    
            // Use custom message parser / writer to customize the way HTTP
            // messages are parsed from and written out to the data stream.
            HttpMessageParserFactory<HttpResponse> responseParserFactory = new DefaultHttpResponseParserFactory() {
    
                @Override
                public HttpMessageParser<HttpResponse> create(
                    SessionInputBuffer buffer, MessageConstraints constraints) {
                    LineParser lineParser = new BasicLineParser() {
    
                        @Override
                        public Header parseHeader(final CharArrayBuffer buffer) {
                            try {
                                return super.parseHeader(buffer);
                            } catch (ParseException ex) {
                                return new BasicHeader(buffer.toString(), null);
                            }
                        }
    
                    };
                    return new DefaultHttpResponseParser(
                        buffer, lineParser, DefaultHttpResponseFactory.INSTANCE, constraints) {
    
                        @Override
                        protected boolean reject(final CharArrayBuffer line, int count) {
                            // try to ignore all garbage preceding a status line infinitely
                            return false;
                        }
    
                    };
                }
    
            };
            HttpMessageWriterFactory<HttpRequest> requestWriterFactory = new DefaultHttpRequestWriterFactory();
    
            // Use a custom connection factory to customize the process of
            // initialization of outgoing HTTP connections. Beside standard connection
            // configuration parameters HTTP connection factory can define message
            // parser / writer routines to be employed by individual connections.
            HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory = new ManagedHttpClientConnectionFactory(
                    requestWriterFactory, responseParserFactory);
    
            // Client HTTP connection objects when fully initialized can be bound to
            // an arbitrary network socket. The process of network socket initialization,
            // its connection to a remote address and binding to a local one is controlled
            // by a connection socket factory.
    
            // SSL context for secure connections can be created either based on
            // system or application specific properties.
            SSLContext sslcontext = SSLContexts.createSystemDefault();
    
            // Create a registry of custom connection socket factories for supported
            // protocol schemes.
            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.INSTANCE)
                .register("https", new SSLConnectionSocketFactory(sslcontext))
                .build();
    
            // Use custom DNS resolver to override the system DNS resolution.
            DnsResolver dnsResolver = new SystemDefaultDnsResolver() {
    
                @Override
                public InetAddress[] resolve(final String host) throws UnknownHostException {
                    if (host.equalsIgnoreCase("myhost")) {
                        return new InetAddress[] { InetAddress.getByAddress(new byte[] {127, 0, 0, 1}) };
                    } else {
                        return super.resolve(host);
                    }
                }
    
            };
    
            // Create a connection manager with custom configuration.
            PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(
                    socketFactoryRegistry, connFactory, dnsResolver);
    
            // Create socket configuration
            SocketConfig socketConfig = SocketConfig.custom()
                .setTcpNoDelay(true)
                .build();
            // Configure the connection manager to use socket configuration either
            // by default or for a specific host.
            connManager.setDefaultSocketConfig(socketConfig);
            connManager.setSocketConfig(new HttpHost("somehost", 80), socketConfig);
            // Validate connections after 1 sec of inactivity
            connManager.setValidateAfterInactivity(1000);
    
            // Create message constraints
            MessageConstraints messageConstraints = MessageConstraints.custom()
                .setMaxHeaderCount(200)
                .setMaxLineLength(2000)
                .build();
            // Create connection configuration
            ConnectionConfig connectionConfig = ConnectionConfig.custom()
                .setMalformedInputAction(CodingErrorAction.IGNORE)
                .setUnmappableInputAction(CodingErrorAction.IGNORE)
                .setCharset(Consts.UTF_8)
                .setMessageConstraints(messageConstraints)
                .build();
            // Configure the connection manager to use connection configuration either
            // by default or for a specific host.
            connManager.setDefaultConnectionConfig(connectionConfig);
            connManager.setConnectionConfig(new HttpHost("somehost", 80), ConnectionConfig.DEFAULT);
    
            // Configure total max or per route limits for persistent connections
            // that can be kept in the pool or leased by the connection manager.
            connManager.setMaxTotal(100);
            connManager.setDefaultMaxPerRoute(10);
            connManager.setMaxPerRoute(new HttpRoute(new HttpHost("somehost", 80)), 20);
    
            // Use custom cookie store if necessary.
            CookieStore cookieStore = new BasicCookieStore();
            // Use custom credentials provider if necessary.
            CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            // Create global request configuration
            RequestConfig defaultRequestConfig = RequestConfig.custom()
                .setCookieSpec(CookieSpecs.DEFAULT)
                .setExpectContinueEnabled(true)
                .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
                .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC))
                .build();
    
            // Create an HttpClient with the given custom dependencies and configuration.
            CloseableHttpClient httpclient = HttpClients.custom()
                .setConnectionManager(connManager)
                .setDefaultCookieStore(cookieStore)
                .setDefaultCredentialsProvider(credentialsProvider)
                .setProxy(new HttpHost("myproxy", 8080))
                .setDefaultRequestConfig(defaultRequestConfig)
                .build();
    
            try {
                HttpGet httpget = new HttpGet("http://httpbin.org/get");
                // Request configuration can be overridden at the request level.
                // They will take precedence over the one set at the client level.
                RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig)
                    .setSocketTimeout(5000)
                    .setConnectTimeout(5000)
                    .setConnectionRequestTimeout(5000)
                    .setProxy(new HttpHost("myotherproxy", 8080))
                    .build();
                httpget.setConfig(requestConfig);
    
                // Execution context can be customized locally.
                HttpClientContext context = HttpClientContext.create();
                // Contextual attributes set the local context level will take
                // precedence over those set at the client level.
                context.setCookieStore(cookieStore);
                context.setCredentialsProvider(credentialsProvider);
    
                System.out.println("executing request " + httpget.getURI());
                CloseableHttpResponse response = httpclient.execute(httpget, context);
                try {
                    System.out.println("----------------------------------------");
                    System.out.println(response.getStatusLine());
                    System.out.println(EntityUtils.toString(response.getEntity()));
                    System.out.println("----------------------------------------");
    
                    // Once the request has been executed the local context can
                    // be used to examine updated state and various objects affected
                    // by the request execution.
    
                    // Last executed request
                    context.getRequest();
                    // Execution route
                    context.getHttpRoute();
                    // Target auth state
                    context.getTargetAuthState();
                    // Proxy auth state
                    context.getProxyAuthState();
                    // Cookie origin
                    context.getCookieOrigin();
                    // Cookie spec used
                    context.getCookieSpec();
                    // User security token
                    context.getUserToken();
    
                } finally {
                    response.close();
                }
            } finally {
                httpclient.close();
            }
        }
    
    }

    END

  • 相关阅读:
    唐骏:学会高明的让员工加班
    [ZT]微软亚洲技术中心面试题[附非標准答案]
    企业的后ERP时代
    WinForm中使用DXperience控件中XtraForm,如何实现换肤
    世卫组织健康食品排行榜:健康肉类减为三种
    [轉載]在研究院的新兵训练
    [转]怎样面对同事升职?
    今天是个好日子!
    程序员跳槽动机被误读,薪资只是表象(图文)
    2008年个人技术十大趋势
  • 原文地址:https://www.cnblogs.com/yangyongjie/p/12575879.html
Copyright © 2011-2022 走看看