Apache Httpclient 简明教程

Apache HttpClient - Quick Guide

Apache HttpClient - Overview

超文本传输协议 (HTTP) 是针对分布式、协作、超媒体信息系统的应用程序级协议。自 1990 年以来,它是万维网(即互联网)数据通信的基础。HTTP 是一种通用且无状态的协议,使用其请求方法、错误代码和标头的扩展,也可将其用于其他目的。

从本质上讲,HTTP 是一种基于 TCP/IP 的通信协议,用于在万维网上传递数据(HTML 文件、图像文件、查询结果等)。默认端口为 TCP 80,但也可以使用其他端口。它提供了一种计算机相互通信的标准化方式。HTTP 规范定义了如何构建和向服务器发送客户端请求数据,以及服务器如何响应这些请求。

What is Http Client

Http 客户端是一个传输库,它驻留在客户端,发送和接收 HTTP 消息。它提供最新、功能丰富且符合最新 HTTP 标准的高效实现。

除了使用客户端库之外,还可以构建基于 HTTP 的应用程序,例如 Web 浏览器、Web 服务客户端等。

Features of Http Client

以下是 Http 客户端的突出功能 -

  1. HttpClient 库实现了所有可用的 HTTP 方法。

  2. HttpClient 库提供 API 来使用安全套接字层协议保护请求。

  3. 使用 HttpClient,可以通过代理建立连接。

  4. 你可以使用基本、摘要、NTLMv1、NTLMv2、NTLM2 会话等身份验证方案对连接进行身份验证。

  5. HttpClient 库支持通过多个线程发送请求。它使用 ClientConnectionPoolManager 管理由不同线程建立的多个连接。

  6. 使用 Apache HttpClient 库,你可以设置连接超时。

Apache HttpClient - Environment Setup

在本教程中,我们将说明如何在 Eclipse IDE 中为 HttpClient 设置环境。在继续安装之前,确保你的系统中已经安装了 Eclipse。如果没有,下载并安装 Eclipse。

有关 Eclipse 的更多信息,请参阅我们的 Eclipse Tutorial

Step 1 - Download the dependency JAR file

打开 HttpClient(组件)网站的官方 homepage 并转到下载页面

httpcomponents downloads

然后,下载最新稳定版本的 HttpClient 。在整个教程中,我们使用版本 4.5.6,因此下载文件 4.5.6.zip

在下载的文件夹中,你会找到一个名为 lib 的文件夹,其中包含要在项目的类路径中添加的必需 Jar 文件,以使用 HttpClient。

Step 2 - Create a project and set build path

打开 eclipse 并创建一个示例项目。右键单击项目,选择选项 Build Path → Configure Build Path ,如下所示。

build path

Libraries 选项卡的 Java Build Path 框架中,单击 Add External JARs

add external jars

然后选择 lib 文件夹中的所有 jar 文件,然后单击 Apply and Close

jar files

在 eclipse 中,您已做好所有准备使用 HttpClient 库。

Apache HttpClient - Http Get Request

GET 方法用于使用给定的 URI 从给定的服务器检索信息。使用 GET 的请求应该只检索数据而不应该对数据有其他影响。

HttpClient API 提供了一个名为 HttpGet 的类,它表示 get 请求方法。

按照下面的步骤使用 HttpClient 库发送 get 请求

Step 1 - Create a HttpClient object

createDefault() 类的 HttpClients 方法返回 CloseableHttpClient 对象,这是 HttpClient 接口的基本实现。

使用此方法,如下所示创建 HttpClient 对象 −

CloseableHttpClient httpclient = HttpClients.createDefault();

Step 2 - Create an HttpGet Object

HttpGet 类表示 HTTPGET 请求,该请求使用 URI 检索给定服务器的信息。

通过实例化此类创建 HTTP GET 请求。此类接受表示 URI 的 String 值的构造函数。

HttpGet httpget = new HttpGet("https://www.tutorialspoint.com/");

Step 3 - Execute the Get Request

execute() 类的 CloseableHttpClient 方法接受 HttpUriRequest(接口)对象(即 HttpGet、HttpPost、HttpPut、HttpHead 等)并返回响应对象。

如下所示使用此方法执行请求 −

HttpResponse httpresponse = httpclient.execute(httpget);

Example

以下示例演示了使用 HttpClient 库执行 HTTP GET 请求。

import java.util.Scanner;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

public class HttpGetExample {

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

      //Creating a HttpClient object
      CloseableHttpClient httpclient = HttpClients.createDefault();

      //Creating a HttpGet object
      HttpGet httpget = new HttpGet("https://www.tutorialspoint.com/ ");

      //Printing the method used
      System.out.println("Request Type: "+httpget.getMethod());

      //Executing the Get request
      HttpResponse httpresponse = httpclient.execute(httpget);

      Scanner sc = new Scanner(httpresponse.getEntity().getContent());

      //Printing the status line
      System.out.println(httpresponse.getStatusLine());
      while(sc.hasNext()) {
         System.out.println(sc.nextLine());
      }
   }
}

Output

上述程序生成以下输出 −

Request Type: GET
<!DOCTYPE html>
<!--[if IE 8]><html class = "ie ie8"> <![endif]-->
<!--[if IE 9]><html class = "ie ie9"> <![endif]-->
<!--[if gt IE 9]><!-->
<html lang = "en-US"> <!--<![endif]-->
<head>
<!-- Basic -->
<meta charset = "utf-8">
<title>Parallax Scrolling, Java Cryptography, YAML, Python Data Science, Java
i18n, GitLab, TestRail, VersionOne, DBUtils, Common CLI, Seaborn, Ansible,
LOLCODE, Current Affairs 2018, Apache Commons Collections</title>
<meta name = "Description" content = "Parallax Scrolling, Java Cryptography, YAML,
Python Data Science, Java i18n, GitLab, TestRail, VersionOne, DBUtils, Common
CLI, Seaborn, Ansible, LOLCODE, Current Affairs 2018, Intellij Idea, Apache
Commons Collections, Java 9, GSON, TestLink, Inter Process Communication (IPC),
Logo, PySpark, Google Tag Manager, Free IFSC Code, SAP Workflow"/>
<meta name = "Keywords" content = "Python Data Science, Java i18n, GitLab,
TestRail, VersionOne, DBUtils, Common CLI, Seaborn, Ansible, LOLCODE, Gson,
TestLink, Inter Process Communication (IPC), Logo"/>
<meta http-equiv = "X-UA-Compatible" content = "IE = edge">
<meta name = "viewport" content = "width = device-width,initial-scale = 1.0,userscalable = yes">
<link href = "https://cdn.muicss.com/mui-0.9.39/extra/mui-rem.min.css"
rel = "stylesheet" type = "text/css" />
<link rel = "stylesheet" href="/questions/css/home.css?v = 3" />
<script src = "/questions/js/jquery.min.js"></script>
<script src = "/questions/js/fontawesome.js"></script>
<script src = "https://cdn.muicss.com/mui-0.9.39/js/mui.min.js"></script>
</head>
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
</script>
</body>
</html>

Apache HttpClient - Http Post Request

POST请求用于将数据发送到服务器;例如,使用HTML表单发送客户信息、文件上传等。

HttpClient API提供了一个名为 HttpPost 的类,它表示POST请求。

按照以下步骤,使用HttpClient库发送HTTP POST请求。

Step 1 - Create an HttpClient Object

HttpClients 类的 createDefault() 方法返回一个 CloseableHttpClient 类的对象,这是 HttpClient 接口的基本实现。

使用此方法创建一个HttpClient对象。

CloseableHttpClient httpClient = HttpClients.createDefault();

Step 2 - Create HttpPost Object

HttpPost 类表示 HTTP POST 请求。它发送所需的数据并使用URI检索给定服务器的信息。

通过实例化 HttpPost 类并传递一个表示URI的字符串值作为其构造函数的参数,来创建此请求。

HttpGet httpGet = new HttpGet("https://www.tutorialspoint.com/");

Step 3 - Execute the Get Request

CloseableHttpClient对象的 execute() 方法接受一个HttpUriRequest(接口)对象(即HttpGet、HttpPost、HttpPut、HttpHead等),并返回一个响应对象。

HttpResponse httpResponse = httpclient.execute(httpget);

Example

以下是演示如何使用HttpClient库执行HTTP POST请求的示例。

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

public class HttpPostExample {

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

      //Creating a HttpClient object
      CloseableHttpClient httpclient = HttpClients.createDefault();

      //Creating a HttpGet object
      HttpPost httppost = new HttpPost("https://www.tutorialspoint.com/");

      //Printing the method used
      System.out.println("Request Type: "+httppost.getMethod());

      //Executing the Get request
      HttpResponse httpresponse = httpclient.execute(httppost);

      Scanner sc = new Scanner(httpresponse.getEntity().getContent());

      //Printing the status line
      System.out.println(httpresponse.getStatusLine());
      while(sc.hasNext()) {
         System.out.println(sc.nextLine());
      }
   }
}

Output

上述程序产生以下输出。

Request Type: POST
<!DOCTYPE html>
<!--[if IE 8]><html class = "ie ie8"> <![endif]-->
<!--[if IE 9]><html class = "ie ie9"> <![endif]-->
<!--[if gt IE 9]><!-->
<html lang = "en-US"> <!--<![endif]-->
<head>
<!-- Basic -->
<meta charset = "utf-8">
<title>Parallax Scrolling, Java Cryptography, YAML, Python Data Science, Java
i18n, GitLab, TestRail, VersionOne, DBUtils, Common CLI, Seaborn, Ansible,
LOLCODE, Current Affairs 2018, Apache Commons Collections</title>
<meta name = "Description" content = "Parallax Scrolling, Java Cryptography, YAML,
Python Data Science, Java i18n, GitLab, TestRail, VersionOne, DBUtils, Common
CLI, Seaborn, Ansible, LOLCODE, Current Affairs 2018, Intellij Idea, Apache
Commons Collections, Java 9, GSON, TestLink, Inter Process Communication (IPC),
Logo, PySpark, Google Tag Manager, Free IFSC Code, SAP Workflow"/>
<meta name = "Keywords" content="Python Data Science, Java i18n, GitLab,
TestRail, VersionOne, DBUtils, Common CLI, Seaborn, Ansible, LOLCODE, Gson,
TestLink, Inter Process Communication (IPC), Logo"/>
<meta http-equiv = "X-UA-Compatible" content = "IE = edge">
<meta name = "viewport" conten t= "width = device-width,initial-scale = 1.0,userscalable = yes">
<link href = "https://cdn.muicss.com/mui-0.9.39/extra/mui-rem.min.css"
rel = "stylesheet" type = "text/css" />
<link rel = "stylesheet" href = "/questions/css/home.css?v = 3" />
<script src = "/questions/js/jquery.min.js"></script>
<script src = "/questions/js/fontawesome.js"></script>
<script src = "https://cdn.muicss.com/mui-0.9.39/js/mui.min.js"></script>
</head>
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
</script>
</body>
</html>

Apache HttpClient - Response Handlers

建议使用响应处理程序处理 HTTP 响应。在本章中,我们将讨论如何创建响应处理程序以及如何使用它们处理响应。

如果您使用响应处理程序,那么所有的 HTTP 连接都将自动释放。

Creating a response handler

HttpClient API 在包 org.apache.http.client. 中提供了一个称为 ResponseHandler 的接口。为了创建响应处理程序,请实现此接口并覆盖其 handleResponse() 方法。

每个响应都有一个状态代码,如果状态代码在 200 和 300 之间,则表示该操作已成功收到、理解和接受。因此,在我们的示例中,我们将处理具有此类状态代码的响应的实体。

Executing the request using response handler

按照下面给出的步骤来使用响应处理程序执行请求。

Step 1 - Create an HttpClient Object

createDefault() 类的 HttpClients 方法返回 CloseableHttpClient 类的对象,这是 HttpClient 接口的基本实现。使用此方法创建 HttpClient 对象

CloseableHttpClient httpclient = HttpClients.createDefault();

Step 2 - Instantiate the Response Handler

使用以下代码行实例化上面创建的响应处理程序对象 −

ResponseHandler<String> responseHandler = new MyResponseHandler();

Step 3 - Create a HttpGet Object

HttpGet 类表示使用 URI 检索给定服务器信息的 HTTP GET 请求。

通过实例化 HttpGet 类并向其构造函数传递表示 URI 的字符串作为参数创建 HttpGet 请求。

ResponseHandler<String> responseHandler = new MyResponseHandler();

Step 4 - Execute the Get request using response handler

CloseableHttpClient 类有一个 execute() 方法的变体,它接受两个对象 ResponseHandler 和 HttpUriRequest,并返回一个响应对象。

String httpResponse = httpclient.execute(httpget, responseHandler);

Example

以下示例演示了响应处理程序的使用。

import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

class MyResponseHandler implements ResponseHandler<String>{

   public String handleResponse(final HttpResponse response) throws IOException{

      //Get the status of the response
      int status = response.getStatusLine().getStatusCode();
      if (status >= 200 && status < 300) {
         HttpEntity entity = response.getEntity();
         if(entity == null) {
            return "";
         } else {
            return EntityUtils.toString(entity);
         }

      } else {
         return ""+status;
      }
   }
}

public class ResponseHandlerExample {

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

      //Create an HttpClient object
      CloseableHttpClient httpclient = HttpClients.createDefault();

      //instantiate the response handler
      ResponseHandler<String> responseHandler = new MyResponseHandler();

      //Create an HttpGet object
      HttpGet httpget = new HttpGet("https://www.tutorialspoint.com/");

      //Execute the Get request by passing the response handler object and HttpGet object
      String httpresponse = httpclient.execute(httpget, responseHandler);

      System.out.println(httpresponse);
   }
}

Output

上述程序生成以下输出 −

<!DOCTYPE html>
<!--[if IE 8]><html class = "ie ie8"> <![endif]-->
<!--[if IE 9]><html class = "ie ie9"> <![endif]-->
<!--[if gt IE 9]><!-->
<html lang = "en-US"> <!--<![endif]-->
<head>
<!-- Basic -->
<meta charset = "utf-8">
<meta http-equiv = "X-UA-Compatible" content = "IE = edge">
<meta name = "viewport" content = "width = device-width,initial-scale = 1.0,userscalable = yes">
<link href = "https://cdn.muicss.com/mui-0.9.39/extra/mui-rem.min.css"
rel = "stylesheet" type = "text/css" />
<link rel = "stylesheet" href = "/questions/css/home.css?v = 3" />
<script src = "/questions/js/jquery.min.js"></script>
<script src = "/questions/js/fontawesome.js"></script>
<script src = "https://cdn.muicss.com/mui-0.9.39/js/mui.min.js"></script>
</head>
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-232293-17');
</script>
</body>

Apache HttpClient - Closing Connection

如果你手动处理 HTTP 响应而不是使用响应处理程序,你需要自己关闭所有 http 连接。本章解释了如何手动关闭连接。

手动关闭 HTTP 连接时遵循以下步骤 −

Step 1 - Create an HttpClient object

HttpClients 类的 createDefault() 方法返回类 CloseableHttpClient 的一个对象,它是 HttpClient 接口的基本实现。

使用此方法,创建一个 HttpClient 对象,如下所示 −

CloseableHttpClient httpClient = HttpClients.createDefault();

Step 2 - Start a try-finally block

启动一个 try-finally 块,在 try 块中编写程序中的其余代码,并在 finally 块中关闭 CloseableHttpClient 对象。

CloseableHttpClient httpClient = HttpClients.createDefault();
try{
   //Remaining code . . . . . . . . . . . . . . .
}finally{
   httpClient.close();
}

Step 3 - Create a HttpGetobject

HttpGet 类表示使用 URI 检索给定服务器信息的 HTTP GET 请求。

通过实例化 HttpGet 类来创建 HTTP GET 请求,并传入一个表示 URI 的字符串。

HttpGet httpGet = new HttpGet("https://www.tutorialspoint.com/");

Step 4 - Execute the Get request

CloseableHttpClient 对象的 execute() 方法接受一个 HttpUriRequest (接口)对象(即 HttpGet、HttpPost、HttpPut、HttpHead 等),并返回一个响应对象。

使用给定方法执行请求 −

HttpResponse httpResponse = httpclient.execute(httpGet);

Step 5 - Start another (nested) try-finally

启动另一个 try-finally 块(嵌套在前一个 try-finally 中),在此 try 块中编写程序中的其余代码,并在 finally 块中关闭 HttpResponse 对象。

CloseableHttpClient httpclient = HttpClients.createDefault();
try{
   . . . . . . .
   . . . . . . .
   CloseableHttpResponse httpresponse = httpclient.execute(httpget);
   try{
      . . . . . . .
      . . . . . . .
   }finally{
      httpresponse.close();
   }
}finally{
   httpclient.close();
}

Example

每当你创建/获取对象(如请求、响应流等)时,就在下一行中启动一个 try finally 块,在 try 中编写剩余代码,并在 finally 块中关闭相应对象,如下一个程序中所示 −

import java.util.Scanner;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

public class CloseConnectionExample {

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

      //Create an HttpClient object
      CloseableHttpClient httpclient = HttpClients.createDefault();

      try{
         //Create an HttpGet object
         HttpGet httpget = new HttpGet("https://www.tutorialspoint.com/");

         //Execute the Get request
         CloseableHttpResponse httpresponse = httpclient.execute(httpget);

         try{
            Scanner sc = new Scanner(httpresponse.getEntity().getContent());
            while(sc.hasNext()) {
               System.out.println(sc.nextLine());
            }
         }finally{
            httpresponse.close();
         }
      }finally{
         httpclient.close();
      }
   }
}

Output

在执行上述程序时,生成以下输出 −

<!DOCTYPE html>
<!--[if IE 8]><html class = "ie ie8"> <![endif]-->
<!--[if IE 9]><html class = "ie ie9"> <![endif]-->
<!--[if gt IE 9]><!-->
<html lang = "en-US"> <!--<![endif]-->
<head>
<!-- Basic -->
<meta charset = "utf-8">
<meta http-equiv = "X-UA-Compatible" content = "IE = edge">
<meta name = "viewport" content = "width = device-width,initial-scale = 1.0,userscalable = yes">
<link href = "https://cdn.muicss.com/mui-0.9.39/extra/mui-rem.min.css"
rel = "stylesheet" type = "text/css" />
<link rel = "stylesheet" href = "/questions/css/home.css?v = 3" />
<script src = "/questions/js/jquery.min.js"></script>
<script src = "/questions/js/fontawesome.js"></script>
<script src = "https://cdn.muicss.com/mui-0.9.39/js/mui.min.js"></script>
</head>
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-232293-17');
</script>
</body>
</html>

Apache HttpClient - Aborting a Request

你可以使用 abort() 方法中止当前的 HTTP 请求,即在对特定请求调用此方法后,将中止其执行。

如果在一次执行后调用此方法,则该执行的响应不会受到影响,后续执行将被中止。

Example

如果你看到以下示例,我们创建了一个 HttpGet 请求,使用 getMethod() 打印了使用的请求格式。

随后,我们使用相同的请求执行了另一个执行。再次利用第一个执行打印状态行。最后,打印第二个执行的状态行。

如所讨论的,打印了第一个执行的响应(中断方法之前的执行)(包括中断方法之后写入的第二个状态行),并且在中断方法执行后当前请求的所有后续执行都将失败,从而引发异常。

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

public class HttpGetExample {
   public static void main(String args[]) throws Exception{

      //Creating an HttpClient object
      CloseableHttpClient httpclient = HttpClients.createDefault();

      //Creating an HttpGet object
      HttpGet httpget = new HttpGet("https://www.tutorialspoint.com/");

      //Printing the method used
      System.out.println(httpget.getMethod());

      //Executing the Get request
      HttpResponse httpresponse = httpclient.execute(httpget);

      //Printing the status line
      System.out.println(httpresponse.getStatusLine());

      httpget.abort();
      System.out.println(httpresponse.getEntity().getContentLength());

      //Executing the Get request
      HttpResponse httpresponse2 = httpclient.execute(httpget);
      System.out.println(httpresponse2.getStatusLine());
   }
}

Output

执行后,上述程序会生成以下输出−

On executing, the above program generates the following output.
GET
HTTP/1.1 200 OK
-1
Exception in thread "main" org.apache.http.impl.execchain.RequestAbortedException:
Request aborted
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:180)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
at HttpGetExample.main(HttpGetExample.java:32)

Apache HttpClient - Interceptors

拦截器是帮助阻塞或更改请求或响应的拦截器。协议拦截器通常作用于特定标头或一组相关标头。HttpClient 库提供对拦截器的支持。

Request interceptor

HttpRequestInterceptor 接口表示请求拦截器。此接口包含一个称为 process 的方法,您需要在其中编写代码块以拦截请求。

在客户端,此方法在将请求发送到服务器之前验证/处理请求,并且在服务器端,此方法在评估请求体之前执行。

Creating request interceptor

您可以按照以下步骤创建请求拦截器。

Step 1 - Create an object of HttpRequestInterceptor

通过实现其抽象方法 process 来创建 HttpRequestInterceptor 接口的对象。

HttpRequestInterceptor requestInterceptor = new HttpRequestInterceptor() {
@Override
 public void process(HttpRequest request, HttpContext context) throws
HttpException, IOException {
   //Method implementation . . . . .
};

Step 2 - Instantiate CloseableHttpClient object

通过将上述创建的拦截器添加到它来构建一个自定义 CloseableHttpClient 对象,如下所示 −

//Creating a CloseableHttpClient object
CloseableHttpClient httpclient =
HttpClients.custom().addInterceptorFirst(requestInterceptor).build();

使用此对象,您可以像往常一样执行请求执行。

Example

下面的示例演示了请求拦截器的用法。在此示例中,我们创建了一个 HTTP GET 请求对象,并向其中添加了三个标头:sample-header、demoheader 和 test-header。

在拦截器的 processor() 方法中,我们正在验证发送的请求的标头;如果其中任何标头为 sample-header ,我们将尝试将其删除并显示该特定请求的标头列表。

import java.io.IOException;
import org.apache.http.Header;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HttpContext;

public class InterceptorsExample {

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

      //Creating an HttpRequestInterceptor
      HttpRequestInterceptor requestInterceptor = new HttpRequestInterceptor() {
         @Override
         public void process(HttpRequest request, HttpContext context) throws
         HttpException, IOException {
            if(request.containsHeader("sample-header")) {
               System.out.println("Contains header sample-header, removing it..");
               request.removeHeaders("sample-header");
            }
            //Printing remaining list of headers
            Header[] headers= request.getAllHeaders();
            for (int i = 0; i<headers.length;i++) {
               System.out.println(headers[i].getName());
            }
         }
      };

      //Creating a CloseableHttpClient object
      CloseableHttpClient httpclient =
      HttpClients.custom().addInterceptorFirst(requestInterceptor).build();

      //Creating a request object
      HttpGet httpget1 = new HttpGet("https://www.tutorialspoint.com/");

      //Setting the header to it
      httpget1.setHeader(new BasicHeader("sample-header","My first header"));
      httpget1.setHeader(new BasicHeader("demo-header","My second header"));
      httpget1.setHeader(new BasicHeader("test-header","My third header"));

      //Executing the request
      HttpResponse httpresponse = httpclient.execute(httpget1);

      //Printing the status line
      System.out.println(httpresponse.getStatusLine());
   }
}

Output

在执行上述程序时,生成以下输出 −

Contains header sample-header, removing it..
demo-header
test-header
HTTP/1.1 200 OK

Response interceptor

HttpResponseInterceptor 接口表示响应拦截器。此接口包含一个称为 process() 的方法。在此方法中,您需要编写代码块以拦截响应。

在服务器端,此方法在将响应发送到客户端之前验证/处理响应,并且在客户端,此方法在评估响应体之前执行。

Creating response interceptor

您可以按照以下步骤创建响应拦截器 −

Step 1 - Create an object of HttpResponseInterceptor

通过实现其抽象方法 process 来创建 HttpResponseInterceptor 接口的对象。

HttpResponseInterceptor responseInterceptor = new HttpResponseInterceptor() {
   @Override
   public void process(HttpResponse response, HttpContext context) throws HttpException, IOException {
      //Method implementation . . . . . . . .
   }
};

Step 2: Instantiate CloseableHttpClient object

通过将上述创建的拦截器添加到它来构建一个自定义 CloseableHttpClient 对象,如下所示 −

//Creating a CloseableHttpClient object
CloseableHttpClient httpclient =
HttpClients.custom().addInterceptorFirst(responseInterceptor).build();

使用此对象,您可以像往常一样执行请求执行。

Example

以下示例演示了请求拦截器用法。在此示例中,已将三个标头添加到了处理器中的响应中:sample-header、demo-header 以及 test-header。

在执行请求和获取响应后,使用了 getAllHeaders() 方法打印了响应的所有标头的名称。

您可以在输出中观察到列表中的三个标头名称。

import java.io.IOException;
import org.apache.http.Header;
import org.apache.http.HttpException;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HttpContext;

public class ResponseInterceptorsExample {

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

      //Creating an HttpRequestInterceptor
      HttpResponseInterceptor responseInterceptor = new HttpResponseInterceptor() {
         @Override
         public void process(HttpResponse response, HttpContext context) throws
         HttpException, IOException {
            System.out.println("Adding header sample_header, demo-header, test_header to the response");
            response.setHeader("sample-header", "My first header");
            response.setHeader("demo-header", "My second header");
            response.setHeader("test-header", "My third header");
         }
      };

      //Creating a CloseableHttpClient object
      CloseableHttpClient httpclient = HttpClients.custom().addInterceptorFirst(responseInterceptor).build();

      //Creating a request object
      HttpGet httpget1 = new HttpGet("https://www.tutorialspoint.com/");

      //Executing the request
      HttpResponse httpresponse = httpclient.execute(httpget1);

      //Printing remaining list of headers
      Header[] headers = httpresponse.getAllHeaders();

      for (int i = 0; i<headers.length;i++) {
         System.out.println(headers[i].getName());
      }
   }
}

Output

在执行上述程序后,生成了以下结果 -

On executing the above program generates the following output.
Adding header sample_header, demo-header, test_header to the response
Accept-Ranges
Access-Control-Allow-Headers
Access-Control-Allow-Origin
Cache-Control
Content-Type
Date
Expires
Last-Modified
Server
Vary
X-Cache
sample-header
demo-header
test-header

Apache HttpClient - User Authentication

使用 HttpClient,您可以连接到需要用户名和密码的网站。本章说明了如何针对询问用户名和密码的网站执行客户端请求。

Step 1 - Create a CredentialsProvider object

CredentialsProvider 接口维护一个用于保存用户登录凭据的集合。通过实例化 BasicCredentialsProvider 类(此接口的默认实现),您可以创建其对象。

CredentialsProvider credentialsPovider = new BasicCredentialsProvider();

Step 2 - Set the Credentials

可以使用 setCredentials() 方法将所需凭据设置为 CredentialsProvider 对象。

此方法接受两个对象,如下所示 -

  1. AuthScope object − 身份验证范围指定详细信息,如主机名、端口号和身份验证方案名称。

  2. Credentials object - 指定凭据(用户名、密码)。

使用 setCredentials() 方法为主机和代理设置凭据,如下所示 -

credsProvider.setCredentials(new AuthScope("example.com", 80),
   new UsernamePasswordCredentials("user", "mypass"));
credsProvider.setCredentials(new AuthScope("localhost", 8000),
   new UsernamePasswordCredentials("abc", "passwd"));

Step 3 - Create a HttpClientBuilder Object

使用 HttpClients 类的 custom() 方法创建一个 HttpClientBuilder

//Creating the HttpClientBuilder
HttpClientBuilder clientbuilder = HttpClients.custom();

Step 4 - Set the credentialsPovider

可以使用 setDefaultCredentialsProvider() 方法将上面创建的 credentialsPovider 对象设置到 HttpClientBuilder。

通过将此前步骤中创建的 CredentialProvider 对象传递给 CredentialsProvider object() 方法,将其设置为客户端构建器,如下所示。

clientbuilder = clientbuilder.setDefaultCredentialsProvider(credsProvider);

Step 5 - Build the CloseableHttpClient

使用 HttpClientBuilder 类的 build() 方法构建 CloseableHttpClient 对象。

CloseableHttpClient httpclient = clientbuilder.build()

Step 6 - Create a HttpGet object and execute it

通过实例化 HttpGet 类创建一个 HttpRequest 对象。使用 execute() 方法执行此请求。

//Creating a HttpGet object
HttpGet httpget = new HttpGet("https://www.tutorialspoint.com/ ");

//Executing the Get request
HttpResponse httpresponse = httpclient.execute(httpget);

Example

以下示例程序演示了针对需要用户身份验证的目标网站执行 HTTP 请求的过程。

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;

public class UserAuthenticationExample {

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

      //Create an object of credentialsProvider
      CredentialsProvider credentialsPovider = new BasicCredentialsProvider();

      //Set the credentials
      AuthScope scope = new AuthScope("https://www.tutorialspoint.com/questions/", 80);

      Credentials credentials = new UsernamePasswordCredentials("USERNAME", "PASSWORD");
      credentialsPovider.setCredentials(scope,credentials);

      //Creating the HttpClientBuilder
      HttpClientBuilder clientbuilder = HttpClients.custom();

      //Setting the credentials
      clientbuilder = clientbuilder.setDefaultCredentialsProvider(credentialsPovider);

      //Building the CloseableHttpClient object
      CloseableHttpClient httpclient = clientbuilder.build();

      //Creating a HttpGet object
      HttpGet httpget = new HttpGet("https://www.tutorialspoint.com/questions/index.php");

      //Printing the method used
      System.out.println(httpget.getMethod());

      //Executing the Get request
      HttpResponse httpresponse = httpclient.execute(httpget);

      //Printing the status line
      System.out.println(httpresponse.getStatusLine());
      int statusCode = httpresponse.getStatusLine().getStatusCode();
      System.out.println(statusCode);

      Header[] headers= httpresponse.getAllHeaders();
      for (int i = 0; i<headers.length;i++) {
         System.out.println(headers[i].getName());
      }
   }
}

Output

在执行上述程序时,将生成以下输出。

GET
HTTP/1.1 200 OK
200

Apache HttpClient - Using Proxy

代理服务器是介于客户端和互联网之间的中间服务器。代理服务器提供的基本功能包括 -

  1. 防火墙和网络数据过滤

  2. Network connection sharing

  3. Data caching

使用 HttpClient 库,您可以通过代理发送 HTTP 请求。请按照以下步骤操作 -

Step 1 - Create a HttpHost object

通过传递表示代理主机名称的字符串参数(你需要从中发送请求),来实例化`@ {s1}`包中的`@ {s0}`类。

//Creating an HttpHost object for proxy
HttpHost proxyHost = new HttpHost("localhost");

以同样的方法,创建另一个`HttpHost`对象来表示需要发送请求的目标主机。

//Creating an HttpHost object for target
HttpHost targetHost = new HttpHost("google.com");

Step 2 - Create an HttpRoutePlanner object

@ {s2}`接口计算到指定主机的一条路由。通过实例化@ {s3}`类,该接口的实现来创建一个此接口的对象。作为其构造函数的参数,传递上面创建的代理主机 -

//creating a RoutePlanner object
HttpRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxyhost);

Step 3 - Set the route planner to a client builder

使用`@ {s5}`类的`@ {s4}`方法,创建一个`@ {s6}`对象,并使用`@ {s7}`方法将上面创建的路由计划程序设置到此对象。

//Setting the route planner to the HttpClientBuilder object
HttpClientBuilder clientBuilder = HttpClients.custom();

clientBuilder = clientBuilder.setRoutePlanner(routePlanner);

Step 4 - Build the CloseableHttpClient object

通过调用`@ {s9}`方法来构建`@ {s8}`对象。

//Building a CloseableHttpClient
CloseableHttpClient httpClient = clientBuilder.build();

Step 5 - Create a HttpGetobject

通过实例化`@ {s10}`类来创建一个HTTP GET请求。

//Creating an HttpGet object
HttpGet httpGet = new HttpGet("/");

Step 6 - Execute the request

@ {s11}`方法的一个变体接受@ {s12}`和`@ {s13}`对象并执行该请求。使用这种方法执行请求 -

//Executing the Get request
HttpResponse httpResponse = httpclient.execute(targetHost, httpGet);

Example

以下示例演示了如何通过代理将HTTP请求发送到服务器。在本例中,我们正在通过本地主机向google.com发送HTTP GET请求。我们已经打印了响应中的头和响应中的正文。

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.routing.HttpRoutePlanner;
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.DefaultProxyRoutePlanner;
import org.apache.http.util.EntityUtils;

public class RequestViaProxyExample {

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

      //Creating an HttpHost object for proxy
      HttpHost proxyhost = new HttpHost("localhost");

      //Creating an HttpHost object for target
      HttpHost targethost = new HttpHost("google.com");

      //creating a RoutePlanner object
      HttpRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxyhost);

      //Setting the route planner to the HttpClientBuilder object
      HttpClientBuilder clientBuilder = HttpClients.custom();
      clientBuilder = clientBuilder.setRoutePlanner(routePlanner);

      //Building a CloseableHttpClient
      CloseableHttpClient httpclient = clientBuilder.build();

      //Creating an HttpGet object
      HttpGet httpget = new HttpGet("/");

      //Executing the Get request
      HttpResponse httpresponse = httpclient.execute(targethost, httpget);

      //Printing the status line
      System.out.println(httpresponse.getStatusLine());

      //Printing all the headers of the response
      Header[] headers = httpresponse.getAllHeaders();

      for (int i = 0; i < headers.length; i++) {
         System.out.println(headers[i]);
      }

      //Printing the body of the response
      HttpEntity entity = httpresponse.getEntity();

      if (entity != null) {
         System.out.println(EntityUtils.toString(entity));
      }
   }
}

Output

执行后,上述程序会生成以下输出−

HTTP/1.1 200 OK
Date: Sun, 23 Dec 2018 10:21:47 GMT
Server: Apache/2.4.9 (Win64) PHP/5.5.13
Last-Modified: Tue, 24 Jun 2014 10:46:24 GMT
ETag: "2e-4fc92abc3c000"
Accept-Ranges: bytes
Content-Length: 46
Content-Type: text/html
<html><body><h1>It works!</h1></body></html>

Apache HttpClient - Proxy Authentication

在本章中,我们将学习如何创建一个经过用户名和密码身份验证并通过代理将其传送到目标主机的 HttpRequest,并使用一个示例。

Step 1 - Create a CredentialsProvider object

CredentialsProvider 接口维护一个用于保存用户登录凭据的集合。您可以通过实例化 BasicCredentialsProvider 类(此接口的默认实现)来创建其对象。

CredentialsProvider credentialsPovider = new BasicCredentialsProvider();

Step 2 - Set the credentials

您可以使用 setCredentials() 方法为 CredentialsProvider 对象设置所需的凭据。此方法接受两个对象 −

  1. AuthScope object − 身份验证范围指定详细信息,如主机名、端口号和身份验证方案名称。

  2. Credentials object −指定凭据(用户名,密码)。使用 setCredentials() 方法为主机和代理设置凭据,如下所示。

credsProvider.setCredentials(new AuthScope("example.com", 80), new
   UsernamePasswordCredentials("user", "mypass"));
credsProvider.setCredentials(new AuthScope("localhost", 8000), new
   UsernamePasswordCredentials("abc", "passwd"));

Step 3 - Create an HttpClientBuilder object

使用 HttpClients 类的 custom() 方法创建一个 HttpClientBuilder ,如下所示。

//Creating the HttpClientBuilder
HttpClientBuilder clientbuilder = HttpClients.custom();

Step 4 - Set the CredentialsProvider

可以使用 setDefaultCredentialsProvider() 方法将CredentialsProvider对象设置到HttpClientBuilder对象。将先前创建的 CredentialsProvider 对象传递到此方法中。

clientbuilder = clientbuilder.setDefaultCredentialsProvider(credsProvider);

Step 5 - Build the CloseableHttpClient

使用 build() 方法构建 CloseableHttpClient 对象。

CloseableHttpClient httpclient = clientbuilder.build();

Step 6 - Create the proxy and target hosts

通过实例化 HttpHost 类创建目标和代理主机。

//Creating the target and proxy hosts
HttpHost target = new HttpHost("example.com", 80, "http");
HttpHost proxy = new HttpHost("localhost", 8000, "http");

Step 7 - Set the proxy and build a RequestConfig object

使用 custom() 方法创建一个 RequestConfig.Builder 对象。使用 setProxy() 方法将先前创建的proxyHost对象设置为 RequestConfig.Builder 。最后,使用 build() 方法构建 RequestConfig 对象。

RequestConfig.Builder reqconfigconbuilder= RequestConfig.custom();
reqconfigconbuilder = reqconfigconbuilder.setProxy(proxyHost);
RequestConfig config = reqconfigconbuilder.build();

Step 8 - Create a HttpGet request object and set config object to it.

通过实例化HttpGet类创建 HttpGet 对象。使用 setConfig() 方法将上一步中创建的config对象设置为此对象。

//Create the HttpGet request object
HttpGet httpGet = new HttpGet("/");

//Setting the config to the request
httpget.setConfig(config);

Step 9 - Execute the request

通过将HttpHost对象(目标)和请求(HttpGet)作为参数传递到 execute() 方法中,来执行请求。

HttpResponse httpResponse = httpclient.execute(targetHost, httpget);

Example

下面的示例展示了如何使用用户名和密码通过代理执行HTTP请求。

import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;

public class ProxyAuthenticationExample {
   public static void main(String[] args) throws Exception {

      //Creating the CredentialsProvider object
      CredentialsProvider credsProvider = new BasicCredentialsProvider();

      //Setting the credentials
      credsProvider.setCredentials(new AuthScope("example.com", 80),
         new UsernamePasswordCredentials("user", "mypass"));
      credsProvider.setCredentials(new AuthScope("localhost", 8000),
         new UsernamePasswordCredentials("abc", "passwd"));

      //Creating the HttpClientBuilder
      HttpClientBuilder clientbuilder = HttpClients.custom();

      //Setting the credentials
      clientbuilder = clientbuilder.setDefaultCredentialsProvider(credsProvider);

      //Building the CloseableHttpClient object
      CloseableHttpClient httpclient = clientbuilder.build();


      //Create the target and proxy hosts
      HttpHost targetHost = new HttpHost("example.com", 80, "http");
      HttpHost proxyHost = new HttpHost("localhost", 8000, "http");

      //Setting the proxy
      RequestConfig.Builder reqconfigconbuilder= RequestConfig.custom();
      reqconfigconbuilder = reqconfigconbuilder.setProxy(proxyHost);
      RequestConfig config = reqconfigconbuilder.build();

      //Create the HttpGet request object
      HttpGet httpget = new HttpGet("/");

      //Setting the config to the request
      httpget.setConfig(config);

      //Printing the status line
      HttpResponse response = httpclient.execute(targetHost, httpget);
      System.out.println(response.getStatusLine());

   }
}

Output

执行后,上述程序会生成以下输出−

HTTP/1.1 200 OK

Apache HttpClient - Form-Based Login

使用 HttpClient 库,你可以通过传递参数来发送请求或登录表单。

按照下面给出的步骤,来登录表单。

Step 1 - Create an HttpClient object

@ {s15}`类的@ {s14}`方法返回`@ {s16}`类的对象,该对象是 HttpClient 接口的基本实现。使用此方法,创建一个 HttpClient 对象 -

CloseableHttpClient httpClient = HttpClients.createDefault();

Step 2 - Create a RequestBuilder object

类`@ {s17}`用于通过向其中添加参数来构建请求。如果请求类型为PUT或POST,它会将这些参数作为URL编码实体添加到请求中

使用`post()`方法创建一个 RequestBuilder 对象(POST 类型)。

//Building the post request object
RequestBuilder reqbuilder = RequestBuilder.post();

Step 3 - Set Uri and parameters to the RequestBuilder.

使用RequestBuilder 类的`@ {s18}`和`@ {s19}`方法将URI和参数设置到 RequestBuilder 对象。

//Set URI and parameters
RequestBuilder reqbuilder = reqbuilder.setUri("http://httpbin.org/post");
reqbuilder = reqbuilder1.addParameter("Name", "username").addParameter("password", "password");

Step 4 - Build the HttpUriRequest object

在设置了所需的参数之后,使用`@ {s21}`方法构建`@ {s20}`对象。

//Building the HttpUriRequest object
HttpUriRequest httppost = reqbuilder2.build();

Step 5 - Execute the request

CloseableHttpClient 对象的`execute`方法接受`HttpUriRequest`(接口)对象(例如 HttpGet、HttpPost、HttpPut、HttpHead 等)并返回一个响应对象。

通过将创建好的`HttpUriRequest`传递给`@ {s22}`方法,执行在前一步创建的`HttpUriRequest`。

//Execute the request
HttpResponse httpresponse = httpclient.execute(httppost);

Example

以下示例展示了如何通过发送登录凭据来登录表单。在此,我们已将两个参数`@ {s23}`发送到表单,并试着打印消息实体和请求状态。

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.net.URISyntaxException;

public class FormLoginExample {

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

      //Creating CloseableHttpClient object
      CloseableHttpClient httpclient = HttpClients.createDefault();

      //Creating the RequestBuilder object
      RequestBuilder reqbuilder = RequestBuilder.post();

      //Setting URI and parameters
      RequestBuilder reqbuilder1 = reqbuilder.setUri("http://httpbin.org/post");
      RequestBuilder reqbuilder2 = reqbuilder1.addParameter("Name",
         "username").addParameter("password", "password");

      //Building the HttpUriRequest object
      HttpUriRequest httppost = reqbuilder2.build();

      //Executing the request
      HttpResponse httpresponse = httpclient.execute(httppost);

      //Printing the status and the contents of the response
      System.out.println(EntityUtils.toString(httpresponse.getEntity()));
      System.out.println(httpresponse.getStatusLine());
   }
}

Output

执行后,上述程序会生成以下输出−

{
   "args": {},
   "data": "",
   "files": {},
   "form": {
      "Name": "username",
      "password": "password"
   },
   "headers": {
      "Accept-Encoding": "gzip,deflate",
      "Connection": "close",
      "Content-Length": "31",
      "Content-Type": "application/x-www-form-urlencoded; charset = UTF-8",
      "Host": "httpbin.org",
      "User-Agent": "Apache-HttpClient/4.5.6 (Java/1.8.0_91)"
   },
   "json": null,
   "origin": "117.216.245.180",
   "url": "http://httpbin.org/post"
}
HTTP/1.1 200 OK

Form Login with Cookies

如果你的表单存储了 cookie,则不创建默认`@ {s24}`对象。

Create a CookieStore object 通过实例化 BasicCookieStore 类。

//Creating a BasicCookieStore object
BasicCookieStore cookieStore = new BasicCookieStore();

Create a HttpClientBuilder 使用 HttpClientscustom() 方法。

//Creating an HttpClientBuilder object
HttpClientBuilder clientbuilder = HttpClients.custom();

Set the cookie store to the client builder 使用 setDefaultCookieStore() 方法。

//Setting default cookie store to the client builder object
Clientbuilder = clientbuilder.setDefaultCookieStore(cookieStore);

使用 build() 方法构建 CloseableHttpClient 对象。

//Building the CloseableHttpClient object
CloseableHttpClient httpclient = clientbuilder1.build();

通过执行请求来构建 HttpUriRequest 对象,如上所述。

如果页面存储了 cookie,您传递的参数将被添加到 cookie 存储中。

您可以打印 CookieStore 对象的内容,其中可以看到您的参数(以及页面先前存储的旧参数,如果存在此类参数)。

若要打印 cookie,请使用 getCookies() 方法从 CookieStore 对象中获取所有 cookie。此方法将返回 List 对象。使用迭代器,按照如下方式打印列表对象的內容:

//Printing the cookies
List list = cookieStore.getCookies();

System.out.println("list of cookies");
Iterator it = list.iterator();
if(it.hasNext()) {
   System.out.println(it.next());
}

Apache HttpClient - Cookies Management

Cookie 是存储在客户端计算机上的文本文件,它们被用于各种信息跟踪目的。

HttpClient 为 cookie 提供支持,您可以创建和管理 cookie。

按照下面给出的步骤使用 HttpClient 库创建 cookie。

Step 1 - Create Cookiestore object

CookieStore 接口表示 Cookie 对象的抽象存储。您可以通过实例化 BasicCookieStore 类来创建 cookie 存储,该类是此接口的默认实现。

//Creating the CookieStore object
CookieStore cookieStore = new BasicCookieStore();

Step 2 - Create ClientCookie object

除了 cookie 的功能之外,ClientCookie 还可以获取服务器中的原始 cookie。您可以通过实例化 BasicClientCookie 类来创建客户端 cookie。对于此类的构造函数,您需要传递您希望存储在特定 cookie 中的键值对。

//Creating client cookie
BasicClientCookie clientCookie = new BasicClientCookie("name","Raju");

对于客户端 cookie,可以使用相应的函数来设置/移除路径、值、版本、到期日期、域名、注释和属性。

Calendar myCal = new GregorianCalendar(2018, 9, 26);
Date expiryDate = myCal.getTime();
clientcookie.setExpiryDate(expiryDate);
clientcookie.setPath("/");
clientcookie.setSecure(true);
clientcookie.setValue("25");
clientcookie.setVersion(5);

您可以使用 BasicCookieStore 类的 addCookie() 方法向 cookie 存储中添加 cookie。

将必需的 cookie 添加到 Cookiestore 中。

//Adding the created cookies to cookie store
cookiestore.addCookie(clientcookie);

Example

以下示例演示如何创建 cookie 并将其添加到 cookie 存储中。在此,我们创建了一个 cookie 存储,通过设置域名和路径值创建了一组 cookie,并将这些 cookie 添加到 cookie 存储中。

import org.apache.http.client.CookieStore;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.cookie.BasicClientCookie;

public class CookieHandlingExample {

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

      //Creating the CookieStore object
      CookieStore cookiestore = new BasicCookieStore();

      //Creating client cookies
      BasicClientCookie clientcookie1 = new BasicClientCookie("name","Raju");
      BasicClientCookie clientcookie2 = new BasicClientCookie("age","28");
      BasicClientCookie clientcookie3 = new BasicClientCookie("place","Hyderabad");

      //Setting domains and paths to the created cookies
      clientcookie1.setDomain(".sample.com");
      clientcookie2.setDomain(".sample.com");
      clientcookie3.setDomain(".sample.com");

      clientcookie1.setPath("/");
      clientcookie2.setPath("/");
      clientcookie3.setPath("/");

      //Adding the created cookies to cookie store
      cookiestore.addCookie(clientcookie1);
      cookiestore.addCookie(clientcookie2);
      cookiestore.addCookie(clientcookie3);
   }
}

您可以使用 asicCookieStore 类的 getCookies() 方法获取添加到 cookie 存储中的 cookie。此方法返回包含 cookie 存储中所有 cookie 的列表。

您可以使用迭代器打印 cookie 存储的內容,如下所示:

//Retrieving the cookies
List list = cookieStore.getCookies();

//Creating an iterator to the obtained list
Iterator it = list.iterator();
while(it.hasNext()) {
   System.out.println(it.next());
}

Example

以下示例演示如何从 cookie 存储中检索 cookie。这里,我们向 cookie 存储中添加了一组 cookie,然后将它们取回。

import org.apache.http.client.CookieStore;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.cookie.BasicClientCookie;

public class CookieHandlingExample {

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

      //Creating the CookieStore object
      CookieStore cookiestore = new BasicCookieStore();

      //Creating client cookies
      BasicClientCookie clientcookie1 = new BasicClientCookie("name","Raju");
      BasicClientCookie clientcookie2 = new BasicClientCookie("age","28");
      BasicClientCookie clientcookie3 = new BasicClientCookie("place","Hyderabad");

      //Setting domains and paths to the created cookies
      clientcookie1.setDomain(".sample.com");
      clientcookie2.setDomain(".sample.com");
      clientcookie3.setDomain(".sample.com");

      clientcookie1.setPath("/");
      clientcookie2.setPath("/");
      clientcookie3.setPath("/");

      //Adding the created cookies to cookie store
      cookiestore.addCookie(clientcookie1);
      cookiestore.addCookie(clientcookie2);
      cookiestore.addCookie(clientcookie3);
   }
}

Output

在执行时,此程序生成以下输出:

[version: 0][name: age][value: 28][domain: .sample.com][path: /][expiry: null]
[version: 0][name: name][value: Raju][domain: my.example.com][path: /][expiry:
null]
[version: 0][name: place][value: Hyderabad][domain: .sample.com][path:
/][expiry: null]

Apache HttpClient - Multiple Threads

多线程程序包含两个或多个可以同时运行的部分,每个部分可以在同一时间处理不同的任务,从而充分利用可用资源。

您可以通过编写多线程 HttpClient 程序来执行来自多个线程的请求。

如果您要从线程中连续执行多个客户端请求,则需要创建一个 ClientConnectionPoolManager 。它维护一个 HttpClientConnections 池,并处理来自线程的多个请求。

连接管理器根据路由来聚合连接。如果管理器有针对特定路由的连接,那么它将通过从池中租用现有的连接,而不是创建新的连接来在这些路由中处理新的请求。

按照步骤执行来自多个线程的请求:

Step 1 - Creating the Client Connection Pool Manager

通过实例化 PoolingHttpClientConnectionManager 类来创建客户端连接池管理器。

PoolingHttpClientConnectionManager connManager = new
   PoolingHttpClientConnectionManager();

Step 2 - Set the maximum number of connections

使用 setMaxTotal() 方法设置池中最大连接数。

//Set the maximum number of connections in the pool
connManager.setMaxTotal(100);

Step 3 - Create a ClientBuilder Object

通过使用 setConnectionManager() 方法设置连接管理器来创建一个 ClientBuilder 对象,如下所示:

HttpClientBuilder clientbuilder =
HttpClients.custom().setConnectionManager(connManager);

Step 4 - Create the HttpGet request objects

通过将所需 URI 作为参数传递给其构造函数来实例化 HttpGet 类。

HttpGet httpget1 = new HttpGet("URI1");
HttpGet httpget2 = new HttpGet("URI2");
. . . . . . . . . . . .

Step 5 - Implementing the run method

确保您已经创建了一个类,使其成为一个线程(通过扩展线程类或实现 Runnable 接口),并实现了 run 方法。

public class ClientMultiThreaded extends Thread {
   public void run() {
      //Run method implementation . . . . . . . . . .
   }
}

Step 6 - Create Thread objects

通过实例化上面创建的 Thread 类(ClientMultiThreaded)来创建线程对象。

向这些线程传递一个 HttpClient 对象、相应的 HttpGet 对象和一个表示 ID 的整数。

ClientMultiThreaded thread1 = new ClientMultiThreaded(httpclient,httpget1, 1);
ClientMultiThreaded thread2 = new ClientMultiThreaded(httpclient,httpget2, 2);
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Step 7 - Start and join the threads

使用 start() 方法启动所有线程,并使用 join method() 连接它们。

thread1.start();
thread2.start();
. . . . . . . .
thread1.join();
thread2.join();
. . . . . . . . . . . .

Step 8 - Run method implementation

在 run 方法中,执行请求,检索响应并打印结果。

Example

下面的示例演示了如何从多个线程同时执行 HTTP 请求。在此示例中,我们尝试从各个线程执行各种请求,并尝试打印状态以及每个客户端读取的字节数。

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
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.util.EntityUtils;

public class ClientMultiThreaded extends Thread {
   CloseableHttpClient httpClient;
   HttpGet httpget;
   int id;

   public ClientMultiThreaded(CloseableHttpClient httpClient, HttpGet httpget,
   int id) {
      this.httpClient = httpClient;
      this.httpget = httpget;
      this.id = id;
   }
   @Override
   public void run() {
      try{
         //Executing the request
         CloseableHttpResponse httpresponse = httpClient.execute(httpget);

         //Displaying the status of the request.
         System.out.println("status of thread "+id+":"+httpresponse.getStatusLine());

         //Retrieving the HttpEntity and displaying the no.of bytes read
         HttpEntity entity = httpresponse.getEntity();
         if (entity != null) {
            System.out.println("Bytes read by thread thread "+id+":
               "+EntityUtils.toByteArray(entity).length);
         }
      }catch(Exception e) {
         System.out.println(e.getMessage());
      }
   }

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

      //Creating the Client Connection Pool Manager by instantiating the PoolingHttpClientConnectionManager class.
      PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();

      //Set the maximum number of connections in the pool
      connManager.setMaxTotal(100);

      //Create a ClientBuilder Object by setting the connection manager
      HttpClientBuilder clientbuilder = HttpClients.custom().setConnectionManager(connManager);

      //Build the CloseableHttpClient object using the build() method.
      CloseableHttpClient httpclient = clientbuilder.build();

      //Creating the HttpGet requests
      HttpGet httpget1 = new HttpGet("https://www.tutorialspoint.com/");
      HttpGet httpget2 = new HttpGet("http://www.google.com/");
      HttpGet httpget3 = new HttpGet("https://www.qries.com/");
      HttpGet httpget4 = new HttpGet("https://in.yahoo.com/");

      //Creating the Thread objects
      ClientMultiThreaded thread1 = new ClientMultiThreaded(httpclient,httpget1, 1);
      ClientMultiThreaded thread2 = new ClientMultiThreaded(httpclient,httpget2, 2);
      ClientMultiThreaded thread3 = new ClientMultiThreaded(httpclient,httpget3, 3);
      ClientMultiThreaded thread4 = new ClientMultiThreaded(httpclient,httpget4, 4);

      //Starting all the threads
      thread1.start();
      thread2.start();
      thread3.start();
      thread4.start();

      //Joining all the threads
      thread1.join();
      thread2.join();
      thread3.join();
      thread4.join();
   }
}

Output

执行后,上述程序会生成以下输出−

status of thread 1: HTTP/1.1 200 OK
Bytes read by thread thread 1: 36907
status of thread 2: HTTP/1.1 200 OK
Bytes read by thread thread 2: 13725
status of thread 3: HTTP/1.1 200 OK
Bytes read by thread thread 3: 17319
status of thread 4: HTTP/1.1 200 OK
Bytes read by thread thread 4: 127018

Apache HttpClient - Custom SSL Context

使用安全套接层,您可以在客户端和服务器之间建立安全连接。它有助于保护敏感信息,如信用卡号、用户名、密码、pin 码等。

您可以使用 HttpClient 库创建自己的 SSL 上下文,以使连接更安全。

按照以下步骤使用 HttpClient 库自定义 SSLContext:

Step 1 - Create SSLContextBuilder object

SSLContextBuilder 是 SSLContext 对象的构建器。使用 SSLContexts 类的 custom() 方法创建该对象的实例。

//Creating SSLContextBuilder object
SSLContextBuilder SSLBuilder = SSLContexts.custom();

Step 2 - Load the Keystore

在路径 Java_home_directory/jre/lib/security/ 中,你可以找到一个名为 cacerts 的文件。将其保存为你的密钥存储文件(扩展名为 .jks)。使用 SSLContextBuilder 类的 loadTrustMaterial() 方法加载密钥存储文件及其密码(默认情况下密码为 changeit )。

//Loading the Keystore file
File file = new File("mykeystore.jks");
SSLBuilder = SSLBuilder.loadTrustMaterial(file, "changeit".toCharArray());

Step 3 - build an SSLContext object

SSLContext 对象表示安全套接字协议的实现。使用 build() 方法构建一个 SSLContext。

//Building the SSLContext
SSLContext sslContext = SSLBuilder.build();

Step 4 - Creating SSLConnectionSocketFactory object

SSLConnectionSocketFactory 是 TSL 和 SSL 连接的分层套接字工厂。使用它,你可以使用受信任的证书列表验证 Https 服务器并对给定的 Https 服务器进行身份验证。

你可以通过很多方法创建它。根据创建 SSLConnectionSocketFactory 对象的方式,你可以允许所有主机、仅允许自签名证书、仅允许特定协议等。

To allow only particular protocols ,通过向其构造函数传递 SSLContext 对象、表示需要支持的协议的字符串数组、表示需要支持的密码套件的字符串数组和一个 HostnameVerifier 对象来创建 SSLConnectionSocketFactory 对象。

new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null,
   SSLConnectionSocketFactory.getDefaultHostnameVerifier());

To allow all hosts, 通过传递 SSLContext 对象和 NoopHostnameVerifier 对象来创建 SSLConnectionSocketFactory 对象。

//Creating SSLConnectionSocketFactory SSLConnectionSocketFactory object
SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslcontext, new NoopHostnameVerifier());

Step 5 - Create an HttpClientBuilder object

使用 HttpClients 类的 custom() 方法创建一个 HttpClientBuilder 对象。

//Creating HttpClientBuilder
HttpClientBuilder clientbuilder = HttpClients.custom();

Step 6 - Set the SSLConnectionSocketFactory object

使用 setSSLSocketFactory() 方法将 SSLConnectionSocketFactory 对象设置为 HttpClientBuilder

//Setting the SSLConnectionSocketFactory
clientbuilder = clientbuilder.setSSLSocketFactory(sslConSocFactory);

Step 7 - Build the CloseableHttpClient object

通过调用`@ {s9}`方法来构建`@ {s8}`对象。

//Building the CloseableHttpClient
CloseableHttpClient httpclient = clientbuilder.build();

Step 8 - Create an HttpGet object

HttpGet 类表示使用 URI 检索给定服务器信息的 HTTP GET 请求。

通过实例化 HttpGet 类来创建 HTTP GET 请求,并传入一个表示 URI 的字符串。

//Creating the HttpGet request
HttpGet httpget = new HttpGet("https://example.com/");

Step 9 - Execute the request

使用 execute() 方法执行请求。

//Executing the request
HttpResponse httpresponse = httpclient.execute(httpget);

Example

以下示例演示了 SSLContrext 的自定义:

import java.io.File;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
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.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

public class ClientCustomSSL {

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

      //Creating SSLContextBuilder object
      SSLContextBuilder SSLBuilder = SSLContexts.custom();

      //Loading the Keystore file
      File file = new File("mykeystore.jks");
      SSLBuilder = SSLBuilder.loadTrustMaterial(file,
         "changeit".toCharArray());

      //Building the SSLContext usiong the build() method
      SSLContext sslcontext = SSLBuilder.build();

      //Creating SSLConnectionSocketFactory object
      SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslcontext, new NoopHostnameVerifier());

      //Creating HttpClientBuilder
      HttpClientBuilder clientbuilder = HttpClients.custom();

      //Setting the SSLConnectionSocketFactory
      clientbuilder = clientbuilder.setSSLSocketFactory(sslConSocFactory);

      //Building the CloseableHttpClient
      CloseableHttpClient httpclient = clientbuilder.build();

      //Creating the HttpGet request
      HttpGet httpget = new HttpGet("https://example.com/");

      //Executing the request
      HttpResponse httpresponse = httpclient.execute(httpget);

      //printing the status line
      System.out.println(httpresponse.getStatusLine());

      //Retrieving the HttpEntity and displaying the no.of bytes read
      HttpEntity entity = httpresponse.getEntity();
      if (entity != null) {
         System.out.println(EntityUtils.toByteArray(entity).length);
      }
   }
}

Output

在执行上述程序时,将生成以下输出。

HTTP/1.1 200 OK
1270

Apache HttpClient - Multipart Upload

使用 HttpClient,我们可以执行多部分上传,即,我们可以将较大的对象上传为较小的部分。在本节中,我们通过上传一个简单的文本文件演示了 HTTP 客户端中的多部分上传。

通常,任何多部分上传都包含三个部分。

  1. Initiation of the upload

  2. Uploading the object parts

  3. Completing the Multipart upload

对于使用 HttpClient 的多部分上传,我们需要按照以下步骤进行:

  1. Create a multipart builder.

  2. 向其中添加所需部分。

  3. 完成构建并获取一个多部分 HttpEntity。

  4. 通过设置上述多部分实体来构建请求。

  5. Execute the request.

以下是使用 HttpClient 库上传多部分实体的步骤。

Step 1 - Create an HttpClient object

@ {s15}`类的@ {s14}`方法返回`@ {s16}`类的对象,该对象是 HttpClient 接口的基本实现。使用此方法,创建一个 HttpClient 对象 -

//Creating CloseableHttpClient object
CloseableHttpClient httpclient = HttpClients.createDefault();

Step 2 - Create a FileBody object

FileBody 类表示由文件支持的二进制实体主体。通过传递 File 对象和表示内容类型的 ContentType 对象来实例化该类。

//Creating a File object
File file = new File("sample.txt");

//Creating the FileBody object
FileBody filebody = new FileBody(file, ContentType.DEFAULT_BINARY);

Step 3 - Create a MultipartEntityBuilder

MultipartEntityBuilder 类用于构建多部分 HttpEntity 对象。使用 create() 方法(同类方法)创建其对象。

//Creating the MultipartEntityBuilder
MultipartEntityBuilder entitybuilder = MultipartEntityBuilder.create();

Step 4 - Set the mode

MultipartEntityBuilder 有三种模式:严格模式、RFC6532 和 BROWSER_COMPATIBLE。使用 setMode() 方法将其设置为所需模式。

//Setting the mode
entitybuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

Step 5 - Add various the desired parts

使用 addTextBody()addBinaryBody() 方法,可以将简单文本、文件、流和其他对象添加到 MultipartBuilder 。使用这些方法添加所需内容。

//Adding text
entitybuilder.addTextBody("sample_text", "This is the text part of our file");
//Adding a file
entitybuilder.addBinaryBody("image", new File("logo.png"));

Step 6 - Building single entity

可以使用 MultipartEntityBuilder 类的 build() 方法将所有这些部分构建成单个实体。使用此方法,将所有部分构建成单个 HttpEntity

//Building a single entity using the parts
HttpEntity mutiPartHttpEntity = entityBuilder.build();

Step 7 - Create a RequestBuilder object

RequestBuilder 类用于通过向其中添加参数来构建请求。如果请求类型为 PUT 或 POST,它会以 URL 编码实体的形式将参数添加到请求中。

使用 post() 方法创建 RequestBuilder 对象(类型为 POST)。并将要向其发送请求的 Uri 作为参数传递给它。

//Building the post request object
RequestBuilder reqbuilder = RequestBuilder.post("http://httpbin.org/post");

Step 8 - Set the entity object to the RequestBuilder

使用 RequestBuilder 类的 setEntity() 方法,将上面创建的多部分实体设置为 RequestBuilder。

//Setting the entity object to the RequestBuilder
reqbuilder.setEntity(mutiPartHttpEntity);

Step 9 - Build the HttpUriRequest

使用 RequestBuilder 类的 build() 方法来构建 HttpUriRequest 请求对象。

//Building the request
HttpUriRequest multipartRequest = reqbuilder.build();

Step 10 - Execute the request

使用 execute() 方法执行在上一步中构建的请求(将请求作为参数绕过此方法)。

//Executing the request
HttpResponse httpresponse = httpclient.execute(multipartRequest);

Example

以下示例演示如何使用 HttpClient 库发送多部分请求。在此示例中,我们尝试发送一个由文件支持的多部分请求。

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;

public class MultipartUploadExample {

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

      //Creating CloseableHttpClient object
      CloseableHttpClient httpclient = HttpClients.createDefault();

      //Creating a file object
      File file = new File("sample.txt");

      //Creating the FileBody object
      FileBody filebody = new FileBody(file, ContentType.DEFAULT_BINARY);

      //Creating the MultipartEntityBuilder
      MultipartEntityBuilder entitybuilder = MultipartEntityBuilder.create();

      //Setting the mode
      entitybuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

      //Adding text
      entitybuilder.addTextBody("sample_text", "This is the text part of our file");

      //Adding a file
      entitybuilder.addBinaryBody("image", new File("logo.png"));

      //Building a single entity using the parts
      HttpEntity mutiPartHttpEntity = entitybuilder.build();

      //Building the RequestBuilder request object
      RequestBuilder reqbuilder = RequestBuilder.post("http://httpbin.org/post");

      //Set the entity object to the RequestBuilder
      reqbuilder.setEntity(mutiPartHttpEntity);

      //Building the request
      HttpUriRequest multipartRequest = reqbuilder.build();

      //Executing the request
      HttpResponse httpresponse = httpclient.execute(multipartRequest);

      //Printing the status and the contents of the response
      System.out.println(EntityUtils.toString(httpresponse.getEntity()));
      System.out.println(httpresponse.getStatusLine());
   }
}

Output

执行后,上述程序会生成以下输出−

{
   "args": {},
   "data": "",
   "files": {
      "image": "data:application/octets66PohrH3IWNk1FzpohfdXPIfv9X3490FGcuXsHn9X0piCwomF/xdgADZ9GsfSyvLYAAAAAE
      lFTkSuQmCC"
   },
   "form": {
      "sample_text": "This is the text part of our file"
   },
   "headers": {
      "Accept-Encoding": "gzip,deflate",
      "Connection": "close",
      "Content-Length": "11104",
      "Content-Type": "multipart/form-data;
      boundary=UFJbPHT7mTwpVq70LpZgCi5I2nvxd1g-I8Rt",
      "Host": "httpbin.org",
      "User-Agent": "Apache-HttpClient/4.5.6 (Java/1.8.0_91)"
   },
   "json": null,
   "origin": "117.216.245.180",
   "url": "http://httpbin.org/post"
}
HTTP/1.1 200 OK