Apache Httpclient 简明教程
Apache HttpClient - Overview
超文本传输协议 (HTTP) 是针对分布式、协作、超媒体信息系统的应用程序级协议。自 1990 年以来,它是万维网(即互联网)数据通信的基础。HTTP 是一种通用且无状态的协议,使用其请求方法、错误代码和标头的扩展,也可将其用于其他目的。
从本质上讲,HTTP 是一种基于 TCP/IP 的通信协议,用于在万维网上传递数据(HTML 文件、图像文件、查询结果等)。默认端口为 TCP 80,但也可以使用其他端口。它提供了一种计算机相互通信的标准化方式。HTTP 规范定义了如何构建和向服务器发送客户端请求数据,以及服务器如何响应这些请求。
Apache HttpClient - Environment Setup
在本教程中,我们将说明如何在 Eclipse IDE 中为 HttpClient 设置环境。在继续安装之前,确保你的系统中已经安装了 Eclipse。如果没有,下载并安装 Eclipse。
有关 Eclipse 的更多信息,请参阅我们的 Eclipse Tutorial 。
Step 1 - Download the dependency JAR file
打开 HttpClient(组件)网站的官方 homepage 并转到下载页面
然后,下载最新稳定版本的 HttpClient 。在整个教程中,我们使用版本 4.5.6,因此下载文件 4.5.6.zip 。
在下载的文件夹中,你会找到一个名为 lib 的文件夹,其中包含要在项目的类路径中添加的必需 Jar 文件,以使用 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 之间,则表示该操作已成功收到、理解和接受。因此,在我们的示例中,我们将处理具有此类状态代码的响应的实体。
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());
}
}
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 . . . . . . . .
}
};
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 对象。
此方法接受两个对象,如下所示 -
-
AuthScope object − 身份验证范围指定详细信息,如主机名、端口号和身份验证方案名称。
-
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());
}
}
}
Apache HttpClient - Using Proxy
代理服务器是介于客户端和互联网之间的中间服务器。代理服务器提供的基本功能包括 -
-
防火墙和网络数据过滤
-
Network connection sharing
-
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));
}
}
}
Apache HttpClient - Proxy Authentication
在本章中,我们将学习如何创建一个经过用户名和密码身份验证并通过代理将其传送到目标主机的 HttpRequest,并使用一个示例。
Step 1 - Create a CredentialsProvider object
CredentialsProvider 接口维护一个用于保存用户登录凭据的集合。您可以通过实例化 BasicCredentialsProvider 类(此接口的默认实现)来创建其对象。
CredentialsProvider credentialsPovider = new BasicCredentialsProvider();
Step 2 - Set the credentials
您可以使用 setCredentials() 方法为 CredentialsProvider 对象设置所需的凭据。此方法接受两个对象 −
-
AuthScope object − 身份验证范围指定详细信息,如主机名、端口号和身份验证方案名称。
-
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());
}
}
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 使用 HttpClients 的 custom() 方法。
//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。
Creating a 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");
Step 3 - Set values to the cookie
对于客户端 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);
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);
}
}
Retrieving a cookie
您可以使用 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);
}
}
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();
. . . . . . . . . . . .
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);
}
}
}
Apache HttpClient - Multipart Upload
使用 HttpClient,我们可以执行多部分上传,即,我们可以将较大的对象上传为较小的部分。在本节中,我们通过上传一个简单的文本文件演示了 HTTP 客户端中的多部分上传。
通常,任何多部分上传都包含三个部分。
-
Initiation of the upload
-
Uploading the object parts
-
Completing the Multipart upload
对于使用 HttpClient 的多部分上传,我们需要按照以下步骤进行:
-
Create a multipart builder.
-
向其中添加所需部分。
-
完成构建并获取一个多部分 HttpEntity。
-
通过设置上述多部分实体来构建请求。
-
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