Apache HttpClient4使用教程

基于HttpClient 4.5.2

  1. 執(zhí)行GET請(qǐng)求

    CloseableHttpClient httpClient = HttpClients.custom()
                    .build();
    CloseableHttpResponse response = httpClient.execute(new HttpGet("https://www.baidu.com"));
    System.out.println(EntityUtils.toString(response.getEntity()));
    
  2. 執(zhí)行POST請(qǐng)求

    1. 提交form表單參數(shù)
      CloseableHttpClient httpClient = HttpClients.custom()
              .build();
      HttpPost httpPost = new HttpPost("https://www.explame.com");
      List<NameValuePair> formParams = new ArrayList<NameValuePair>();
      //表單參數(shù)
      formParams.add(new BasicNameValuePair("name1", "value1"));
      formParams.add(new BasicNameValuePair("name2", "value2"));
      UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, "utf-8");
      httpPost.setEntity(entity);
      CloseableHttpResponse response = httpClient.execute(httpPost);
      System.out.println(EntityUtils.toString(response.getEntity()));
      
    2. 提交payload參數(shù)
      CloseableHttpClient httpClient = HttpClients.custom()
                  .build();
      HttpPost httpPost = new HttpPost("https://www.explame.com");
      StringEntity entity = new StringEntity("{\"id\": \"1\"}");
      httpPost.setEntity(entity);
      CloseableHttpResponse response = httpClient.execute(httpPost);
      System.out.println(EntityUtils.toString(response.getEntity()));
      
    3. post上傳文件
      CloseableHttpClient httpClient = HttpClients.custom()
              .build();
      HttpPost httpPost = new HttpPost("https://www.example.com");
      MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
      //要上傳的文件
      multipartEntityBuilder.addBinaryBody("file", new File("temp.txt"));
      httpPost.setEntity(multipartEntityBuilder.build());
      CloseableHttpResponse response = httpClient.execute(httpPost);
      System.out.println(EntityUtils.toString(response.getEntity()));
      
    4. post提交multipart/form-data類型參數(shù)
      CloseableHttpClient httpClient = HttpClients.custom()
              .build();
      HttpPost httpPost = new HttpPost("https://www.example.com");
      MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
      multipartEntityBuilder.addTextBody("username","wycm");
      multipartEntityBuilder.addTextBody("passowrd","123");
      //文件
      multipartEntityBuilder.addBinaryBody("file", new File("temp.txt"));
      httpPost.setEntity(multipartEntityBuilder.build());
      CloseableHttpResponse response = httpClient.execute(httpPost);
      System.out.println(EntityUtils.toString(response.getEntity()));
      
  3. 設(shè)置User-Agent

        CloseableHttpClient httpClient = HttpClients.custom()
                .setUserAgent("Mozilla/5.0")
                .build();
        CloseableHttpResponse response = httpClient.execute(new HttpGet("https://www.baidu.com"));
        System.out.println(EntityUtils.toString(response.getEntity()));
    
  4. 設(shè)置重試處理器
    當(dāng)請(qǐng)求超時(shí), 會(huì)自動(dòng)重試,最多3次

    HttpRequestRetryHandler retryHandler = (exception, executionCount, context) -> {
        if (executionCount >= 3) {
            return false;
        }
        if (exception instanceof InterruptedIOException) {
            return true;
        }
        if (exception instanceof UnknownHostException) {
            return true;
        }
        if (exception instanceof ConnectTimeoutException) {
            return true;
        }
        if (exception instanceof SSLException) {
            return true;
        }
        HttpClientContext clientContext = HttpClientContext.adapt(context);
        HttpRequest request = clientContext.getRequest();
        boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
        if (idempotent) {
            return true;
        }
        return false;
    };
    CloseableHttpClient httpClient = HttpClients.custom()
            .setRetryHandler(retryHandler)
            .build();
    httpClient.execute(new HttpGet("https://www.baidu.com"));
    
  5. 重定向策略

    1. HttpClient默認(rèn)情況
      會(huì)對(duì)302、307的GET和HEAD請(qǐng)求以及所有的303狀態(tài)碼做重定向處理
    2. 關(guān)閉自動(dòng)重定向
      CloseableHttpClient httpClient = HttpClients.custom()
               //關(guān)閉httpclient重定向
              .disableRedirectHandling()
              .build();
      
    3. POST支持302狀態(tài)碼重定向
      CloseableHttpClient httpClient = HttpClients.custom()
          //post 302支持重定向
          .setRedirectStrategy(new LaxRedirectStrategy())
          .build();
      CloseableHttpResponse response = httpClient.execute(new HttpPost("https://www.explame.com"));
      System.out.println(EntityUtils.toString(response.getEntity()));
      
  6. 定制cookie

    • 方式一:通過addHeader方式設(shè)置(不推薦這種方式)
          CloseableHttpClient httpClient = HttpClients.custom()
                  .build();
          HttpGet httpGet = new HttpGet("http://www.example.com");
          httpGet.addHeader("Cookie", "name=value");
          httpClient.execute(httpGet);
      
      由于HttpClient默認(rèn)會(huì)維護(hù)cookie狀態(tài)。如果這個(gè)請(qǐng)求response中有Set-Cookie頭,那下次請(qǐng)求的時(shí)候httpclient默認(rèn)會(huì)把這個(gè)Cookie帶上。并且會(huì)新建一行header。如果再遇到
      httpGet.addHeader("Cookie", "name=value");
      那么下次請(qǐng)求則會(huì)有兩行name為Cookie的header。
    • 方式二:通過CookieStore的方式,以瀏覽器中的cookie為例(推薦)
      //此處直接粘貼瀏覽器cookie
      final String RAW_COOKIES = "name1=value1; name2=value2";
      final CookieStore cookieStore = new BasicCookieStore();
      for (String rawCookie : RAW_COOKIES.split("; ")){
          String[] s = rawCookie.split("=");
          BasicClientCookie cookie = new BasicClientCookie(s[0], s[1]);
          cookie.setDomain("baidu.com");
          cookie.setPath("/");
          cookie.setSecure(false);
          cookie.setAttribute("domain", "baidu.com");
          Calendar calendar = Calendar.getInstance();
          calendar.add(Calendar.DAY_OF_MONTH, +5);
          cookie.setExpiryDate(calendar.getTime());
          cookieStore.addCookie(cookie);
      }
      CloseableHttpClient httpClient = HttpClients.custom()
              .setDefaultCookieStore(cookieStore)
              .build();
      httpClient.execute(new HttpGet("https://www.baidu.com"));
      
      這種方式把定制的cookie交給httpclient維護(hù)。
  7. cookie管理

    • 方式一:初始化HttpClient時(shí),傳入一個(gè)自己CookieStore對(duì)象
      CookieStore cookieStore = new BasicCookieStore();
      CloseableHttpClient httpClient = HttpClients.custom()
              .setDefaultCookieStore(cookieStore)
              .build();
      httpClient.execute(new HttpGet("https://www.baidu.com"));
      //請(qǐng)求一次后,清理cookie再發(fā)起一次新的請(qǐng)求
      cookieStore.clear();
      httpClient.execute(new HttpGet("https://www.baidu.com"));
      
    • 方式二:每次執(zhí)行請(qǐng)求的時(shí)候傳入自己的HttpContext對(duì)象
      //注:HttpClientContext不是線程安全的,不要多個(gè)線程維護(hù)一個(gè)HttpClientContext
      HttpClientContext httpContext = HttpClientContext.create();
      CloseableHttpClient httpClient = HttpClients.custom()
              .build();
      httpClient.execute(new HttpGet("https://www.baidu.com"), httpContext);
      //請(qǐng)求一次后,清理cookie再發(fā)起一次新的請(qǐng)求
      httpContext.getCookieStore().clear();
      httpClient.execute(new HttpGet("https://www.baidu.com"));
      
  8. http代理的配置

    CloseableHttpClient httpClient = HttpClients.custom()
            //設(shè)置代理
            .setRoutePlanner(new DefaultProxyRoutePlanner(new HttpHost("localhost", 8888)))
            .build();
    CloseableHttpResponse response = httpClient.execute(new HttpGet("http://www.example.com"));
    System.out.println(EntityUtils.toString(response.getEntity()));
    
  9. SSL配置

    //默認(rèn)信任
    SSLContext sslContext = SSLContexts.custom()
            .loadTrustMaterial(KeyStore.getInstance(KeyStore.getDefaultType())
                    , (chain, authType) -> true).build();
    Registry<ConnectionSocketFactory> socketFactoryRegistry =
            RegistryBuilder.<ConnectionSocketFactory>create()
                    .register("http", new SocketProxyPlainConnectionSocketFactory())
                    .register("https", new SocketProxySSLConnectionSocketFactory(sslContext))
                    .build();
    CloseableHttpClient httpClient = HttpClients.custom()
            .setConnectionManager(new PoolingHttpClientConnectionManager(socketFactoryRegistry))
            .build();
    HttpClientContext httpClientContext = HttpClientContext.create();
    httpClientContext.setAttribute("socks.address", new InetSocketAddress("127.0.0.1", 1086));
    CloseableHttpResponse response = httpClient.execute(new HttpGet("https://httpbin.org/ip"), httpClientContext);
    System.out.println(EntityUtils.toString(response.getEntity()));
    
  10. socket代理配置

    static class SocketProxyPlainConnectionSocketFactory extends PlainConnectionSocketFactory{
        @Override
        public Socket createSocket(final HttpContext context) {
            InetSocketAddress socksAddr = (InetSocketAddress) context.getAttribute("socks.address");
            if (socksAddr != null){
                Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksAddr);
                return new Socket(proxy);
            } else {
                return new Socket();
            }
        }
    }
    static class SocketProxySSLConnectionSocketFactory extends SSLConnectionSocketFactory {
        public SocketProxySSLConnectionSocketFactory(final SSLContext sslContext) {
            super(sslContext, NoopHostnameVerifier.INSTANCE);
        }
    
        @Override
        public Socket createSocket(final HttpContext context) {
            InetSocketAddress socksAddr = (InetSocketAddress) context.getAttribute("socks.address");
            if (socksAddr != null){
                Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksAddr);
                return new Socket(proxy);
            } else {
                return new Socket();
            }
        }
    
    }
    /**
     * socket代理配置
     */
    public static void socketProxy() throws Exception {
        //默認(rèn)信任
        SSLContext sslContext = SSLContexts.custom()
                .loadTrustMaterial(KeyStore.getInstance(KeyStore.getDefaultType())
                        , (X509Certificate[] chain, String authType) -> true).build();
        Registry<ConnectionSocketFactory> socketFactoryRegistry =
                RegistryBuilder.<ConnectionSocketFactory>create()
                        .register("http", new SocketProxyPlainConnectionSocketFactory())
                        .register("https", new SocketProxySSLConnectionSocketFactory(sslContext))
                        .build();
        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(new PoolingHttpClientConnectionManager(socketFactoryRegistry))
                .build();
        HttpClientContext httpClientContext = HttpClientContext.create();
        httpClientContext.setAttribute("socks.address", new InetSocketAddress("127.0.0.1", 1086));
        CloseableHttpResponse response = httpClient.execute(new HttpGet("https://httpbin.org/ip"), httpClientContext);
        System.out.println(EntityUtils.toString(response.getEntity()));
    }
    
  11. 下載文件

    CloseableHttpClient httpClient = HttpClients.custom().build();
    CloseableHttpResponse response = httpClient.execute(new HttpGet("https://www.example.com"));
    InputStream is = response.getEntity().getContent();
    Files.copy(is, new File("temp.png").toPath(), StandardCopyOption.REPLACE_EXISTING);
    
    

最后

版權(quán)聲明
作者:wycm
出處:http://www.itdecent.cn/p/e6980bb463e9
您的支持是對(duì)博主最大的鼓勵(lì),感謝您的認(rèn)真閱讀。
本文版權(quán)歸作者所有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 每人身上都會(huì)有些與眾不同之處,我也不例外,我身上的特點(diǎn)如同一條條可愛的蟲蟲,時(shí)常會(huì)發(fā)起爭吵呢! ...
    花漾縈心閱讀 359評(píng)論 0 2
  • 清明放假3天,因?yàn)樽罱臼虑楹芏?,很少照顧到孩子學(xué)校的事情,導(dǎo)致最近老師要求家長給孩子做兩個(gè)活動(dòng)PPT,我一直沒...
    rieichin閱讀 255評(píng)論 2 0
  • 1. 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 函數(shù)聲明: 聲明不必放到調(diào)用的前面 函數(shù)表達(dá)式: 聲明必需放到調(diào)用的前...
    peaceChierdo閱讀 256評(píng)論 0 0

友情鏈接更多精彩內(nèi)容