Java使用Apache HttpClient进行网络请求
1. 简介
在Java开发中,进行网络请求是一项常见的任务。Apache HttpClient是一个广泛使用的Java库,它提供了丰富且强大的功能来处理HTTP请求和响应。它支持最新的HTTP标准,并且具有高度可定制性和灵活性,能够满足各种复杂的网络请求场景。
2. 环境搭建
首先,需要在项目中引入Apache HttpClient的依赖。如果使用Maven进行项目管理,可以在pom.xml
文件中添加以下依赖:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
如果使用Gradle,则在build.gradle
文件中添加:
implementation 'org.apache.httpcomponents:httpclient:4.5.13'
确保网络连接正常,因为在实际使用中,HttpClient需要与远程服务器进行通信。
3. 基本的GET请求
3.1 使用CloseableHttpClient创建GET请求
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
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;
import java.io.IOException;
public class GetRequestExample {
public static void main(String[] args) {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("https://www.example.com");
try {
HttpResponse response = httpClient.execute(httpGet);
if (response.getStatusLine().getStatusCode() == 200) {
String responseBody = EntityUtils.toString(response.getEntity());
System.out.println("Response Body: " + responseBody);
} else {
System.out.println("Request failed with status code: " + response.getStatusLine().getStatusCode());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
在上述代码中,首先通过HttpClients.createDefault()
创建了一个默认的CloseableHttpClient
实例。然后创建了一个HttpGet
对象,指定请求的URL。通过httpClient.execute(httpGet)
执行请求并获取HttpResponse
。如果响应状态码为200,说明请求成功,通过EntityUtils.toString(response.getEntity())
获取响应体内容并打印。最后,在finally
块中关闭httpClient
以释放资源。
3.2 设置请求头
有时候需要在GET请求中设置请求头,比如设置User - Agent
。可以通过HttpGet
的setHeader
方法来实现。
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
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;
import java.io.IOException;
public class GetRequestWithHeadersExample {
public static void main(String[] args) {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("https://www.example.com");
httpGet.setHeader("User - Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");
try {
HttpResponse response = httpClient.execute(httpGet);
if (response.getStatusLine().getStatusCode() == 200) {
String responseBody = EntityUtils.toString(response.getEntity());
System.out.println("Response Body: " + responseBody);
} else {
System.out.println("Request failed with status code: " + response.getStatusLine().getStatusCode());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
这里通过httpGet.setHeader("User - Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
设置了User - Agent
请求头,模拟浏览器发送请求。
4. 基本的POST请求
4.1 使用UrlEncodedFormEntity发送表单数据
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class PostRequestExample {
public static void main(String[] args) {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("https://www.example.com/api/post");
List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("username", "testuser"));
params.add(new BasicNameValuePair("password", "testpassword"));
try {
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse response = httpClient.execute(httpPost);
if (response.getStatusLine().getStatusCode() == 200) {
String responseBody = EntityUtils.toString(response.getEntity());
System.out.println("Response Body: " + responseBody);
} else {
System.out.println("Request failed with status code: " + response.getStatusLine().getStatusCode());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
在这段代码中,首先创建了HttpPost
对象并指定请求的URL。然后通过List<NameValuePair>
来存储表单参数,这里添加了username
和password
参数。接着使用UrlEncodedFormEntity
将参数设置到HttpPost
请求中。执行请求后,处理响应并在控制台打印响应体或错误状态码。
4.2 使用MultipartEntityBuilder发送复杂数据(如文件上传)
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
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.entity.mime.content.StringBody;
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;
public class MultipartPostRequestExample {
public static void main(String[] args) {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("https://www.example.com/api/upload");
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addPart("username", new StringBody("testuser", ContentType.TEXT_PLAIN));
File file = new File("path/to/file.txt");
builder.addPart("file", new FileBody(file, ContentType.APPLICATION_OCTET_STREAM));
try {
httpPost.setEntity(builder.build());
HttpResponse response = httpClient.execute(httpPost);
if (response.getStatusLine().getStatusCode() == 200) {
String responseBody = EntityUtils.toString(response.getEntity());
System.out.println("Response Body: " + responseBody);
} else {
System.out.println("Request failed with status code: " + response.getStatusLine().getStatusCode());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
在这个例子中,MultipartEntityBuilder
用于构建复杂的POST请求,比如文件上传。首先设置了请求模式为BROWSER_COMPATIBLE
,然后添加了username
参数作为StringBody
,并添加了一个文件作为FileBody
。最后将构建好的实体设置到HttpPost
请求中并执行请求,处理响应。
5. 处理响应
5.1 获取响应状态码
在前面的示例中,已经展示了如何通过response.getStatusLine().getStatusCode()
获取响应状态码。状态码可以告诉我们请求是否成功,以及失败的原因。常见的状态码有:
- 200:请求成功,服务器已成功处理请求并返回响应。
- 400:客户端请求错误,比如请求参数格式不正确。
- 401:未授权,请求需要用户认证但未提供有效认证信息。
- 404:请求的资源不存在。
- 500:服务器内部错误,服务器在处理请求时发生了错误。
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import java.io.IOException;
public class GetStatusCodeExample {
public static void main(String[] args) {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("https://www.example.com");
try {
HttpResponse response = httpClient.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
System.out.println("Status Code: " + statusCode);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
这段代码只获取并打印响应状态码,用于演示获取状态码的方法。
5.2 获取响应头
可以通过HttpResponse
的getFirstHeader
、getHeaders
等方法获取响应头信息。
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import java.io.IOException;
public class GetResponseHeadersExample {
public static void main(String[] args) {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("https://www.example.com");
try {
HttpResponse response = httpClient.execute(httpGet);
Header contentTypeHeader = response.getFirstHeader("Content - Type");
if (contentTypeHeader != null) {
System.out.println("Content - Type: " + contentTypeHeader.getValue());
}
Header[] allHeaders = response.getHeaders("Cache - Control");
for (Header header : allHeaders) {
System.out.println("Cache - Control: " + header.getValue());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
在上述代码中,使用getFirstHeader
获取Content - Type
响应头的值,使用getHeaders
获取所有Cache - Control
响应头并打印其值。
5.3 获取响应体
前面的示例中已经使用EntityUtils.toString(response.getEntity())
获取了字符串形式的响应体。但如果响应体是二进制数据,比如图片、文件等,就需要使用不同的方法。
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
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;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class GetBinaryResponseBodyExample {
public static void main(String[] args) {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("https://www.example.com/image.jpg");
try {
HttpResponse response = httpClient.execute(httpGet);
if (response.getStatusLine().getStatusCode() == 200) {
InputStream inputStream = response.getEntity().getContent();
FileOutputStream fileOutputStream = new FileOutputStream("downloaded_image.jpg");
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, length);
}
fileOutputStream.close();
inputStream.close();
} else {
System.out.println("Request failed with status code: " + response.getStatusLine().getStatusCode());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
这段代码用于下载图片,通过response.getEntity().getContent()
获取输入流,然后将数据写入本地文件。
6. 连接管理与配置
6.1 连接池
在高并发场景下,频繁地创建和销毁HTTP连接会消耗大量资源,影响性能。Apache HttpClient提供了连接池来管理连接,提高连接的复用率。
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;
import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
public class ConnectionPoolExample {
public static void main(String[] args) throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sslContext = SSLContexts.createSystemDefault();
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslConnectionSocketFactory)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(100);
cm.setDefaultMaxPerRoute(20);
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.setSocketTimeout(5000)
.build();
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(cm)
.setDefaultRequestConfig(requestConfig)
.build();
// 使用httpClient进行请求
}
}
在这段代码中,首先创建了SSLContext
和SSLConnectionSocketFactory
,用于处理HTTPS连接。然后通过RegistryBuilder
注册了HTTP和HTTPS的连接工厂。接着创建了PoolingHttpClientConnectionManager
并设置了最大连接数和每个路由的最大连接数。RequestConfig
用于设置连接超时、请求超时和套接字超时。最后通过HttpClients.custom()
构建了带有连接池和请求配置的CloseableHttpClient
。
6.2 代理设置
如果需要通过代理服务器发送请求,可以在RequestConfig
中进行设置。
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import java.net.InetSocketAddress;
import java.net.Proxy;
public class ProxyExample {
public static void main(String[] args) {
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.example.com", 8080));
RequestConfig requestConfig = RequestConfig.custom()
.setProxy(proxy)
.build();
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultRequestConfig(requestConfig)
.build();
// 使用httpClient进行请求
}
}
这里通过RequestConfig.custom().setProxy(proxy).build()
设置了代理服务器,然后将其应用到CloseableHttpClient
中。
7. 认证机制
7.1 基本认证(Basic Authentication)
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
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.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
public class BasicAuthenticationExample {
public static void main(String[] args) {
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
new AuthScope("www.example.com", 443),
new UsernamePasswordCredentials("username", "password")
);
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultCredentialsProvider(credentialsProvider)
.build();
HttpGet httpGet = new HttpGet("https://www.example.com/api/protected");
try {
httpClient.execute(httpGet);
HttpResponse response = httpClient.execute(httpGet);
if (response.getStatusLine().getStatusCode() == 200) {
String responseBody = EntityUtils.toString(response.getEntity());
System.out.println("Response Body: " + responseBody);
} else {
System.out.println("Request failed with status code: " + response.getStatusLine().getStatusCode());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
在这个示例中,通过BasicCredentialsProvider
设置了用户名和密码,并通过HttpClients.custom().setDefaultCredentialsProvider(credentialsProvider)
将认证信息应用到CloseableHttpClient
中。
7.2 OAuth认证
OAuth认证相对复杂,涉及到获取令牌等多个步骤。这里以OAuth 2.0为例,假设已经获取到了访问令牌。
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
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;
import java.io.IOException;
public class OAuthExample {
public static void main(String[] args) {
String accessToken = "your_access_token";
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("https://www.example.com/api/oauth - protected");
httpGet.setHeader("Authorization", "Bearer " + accessToken);
try {
HttpResponse response = httpClient.execute(httpGet);
if (response.getStatusLine().getStatusCode() == 200) {
String responseBody = EntityUtils.toString(response.getEntity());
System.out.println("Response Body: " + responseBody);
} else {
System.out.println("Request failed with status code: " + response.getStatusLine().getStatusCode());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
在这个代码中,通过在请求头中设置Authorization: Bearer your_access_token
来进行OAuth认证。
8. 异常处理
在使用Apache HttpClient时,可能会遇到各种异常。常见的异常有:
IOException
:这是最常见的异常,可能在执行请求、读取响应等操作时发生,比如网络连接中断、服务器无响应等。在前面的示例中,已经通过catch (IOException e) { e.printStackTrace(); }
来捕获并简单处理这种异常。URISyntaxException
:当请求的URL格式不正确时会抛出此异常。例如:
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import java.net.URISyntaxException;
public class URISyntaxExceptionExample {
public static void main(String[] args) {
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpGet httpGet = new HttpGet("invalid_url");
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}
NoHttpResponseException
:当服务器在一定时间内没有响应时抛出此异常。可以通过设置合适的超时时间来尽量避免这种异常,并且在捕获到该异常时,可以选择重试请求等操作。
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
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;
import java.io.IOException;
public class NoHttpResponseExceptionExample {
public static void main(String[] args) {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("https://www.example.com/slow - responding - endpoint");
try {
HttpResponse response = httpClient.execute(httpGet);
if (response.getStatusLine().getStatusCode() == 200) {
String responseBody = EntityUtils.toString(response.getEntity());
System.out.println("Response Body: " + responseBody);
} else {
System.out.println("Request failed with status code: " + response.getStatusLine().getStatusCode());
}
} catch (IOException e) {
if (e instanceof org.apache.http.NoHttpResponseException) {
// 处理无响应异常,可选择重试
System.out.println("Server did not respond, can retry...");
} else {
e.printStackTrace();
}
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
通过合理地处理这些异常,可以使程序更加健壮,提高用户体验。
9. 高级特性
9.1 异步请求
Apache HttpClient从4.4版本开始支持异步请求,这在处理大量请求或者需要提高响应速度的场景下非常有用。
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.concurrent.Future;
public class AsyncRequestExample {
public static void main(String[] args) {
CloseableHttpAsyncClient httpClient = HttpAsyncClients.createDefault();
httpClient.start();
HttpGet httpGet = new HttpGet("https://www.example.com");
Future<HttpResponse> future = httpClient.execute(httpGet, null);
try {
HttpResponse response = future.get();
if (response.getStatusLine().getStatusCode() == 200) {
String responseBody = EntityUtils.toString(response.getEntity());
System.out.println("Response Body: " + responseBody);
} else {
System.out.println("Request failed with status code: " + response.getStatusLine().getStatusCode());
}
} catch (Exception e) {
e.printStackTrace();
}
httpClient.close();
}
}
在这个示例中,通过HttpAsyncClients.createDefault()
创建了一个异步的CloseableHttpAsyncClient
。然后启动客户端,执行异步请求并通过Future
获取响应。还可以使用FutureCallback
来更灵活地处理异步响应。
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
public class AsyncRequestWithCallbackExample {
public static void main(String[] args) {
CloseableHttpAsyncClient httpClient = HttpAsyncClients.createDefault();
httpClient.start();
HttpGet httpGet = new HttpGet("https://www.example.com");
httpClient.execute(httpGet, new FutureCallback<HttpResponse>() {
@Override
public void completed(HttpResponse response) {
try {
if (response.getStatusLine().getStatusCode() == 200) {
String responseBody = EntityUtils.toString(response.getEntity());
System.out.println("Response Body: " + responseBody);
} else {
System.out.println("Request failed with status code: " + response.getStatusLine().getStatusCode());
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void failed(Exception ex) {
ex.printStackTrace();
}
@Override
public void cancelled() {
System.out.println("Request cancelled");
}
});
// 防止主线程退出
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
httpClient.close();
}
}
这里通过FutureCallback
的completed
方法处理成功的响应,failed
方法处理失败的情况,cancelled
方法处理请求被取消的情况。
9.2 自定义拦截器
可以通过自定义拦截器来对请求和响应进行预处理和后处理。
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpRequestInterceptor;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.Date;
public class CustomInterceptorExample {
public static class MyInterceptor implements HttpRequestInterceptor {
@Override
public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
System.out.println("Request intercepted at " + new Date());
request.addHeader("Custom - Header", "Value");
}
}
public static void main(String[] args) {
CloseableHttpClient httpClient = HttpClients.custom()
.addInterceptorFirst(new MyInterceptor())
.build();
HttpGet httpGet = new HttpGet("https://www.example.com");
try {
HttpResponse response = httpClient.execute(httpGet, HttpClientContext.create());
if (response.getStatusLine().getStatusCode() == 200) {
String responseBody = EntityUtils.toString(response.getEntity());
System.out.println("Response Body: " + responseBody);
} else {
System.out.println("Request failed with status code: " + response.getStatusLine().getStatusCode());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
在这个例子中,自定义了一个MyInterceptor
实现HttpRequestInterceptor
接口,在process
方法中添加了一个自定义请求头并打印拦截时间。然后通过HttpClients.custom().addInterceptorFirst(new MyInterceptor())
将拦截器添加到CloseableHttpClient
中。
通过以上全面深入的介绍,涵盖了从基础的GET、POST请求到高级的连接管理、认证机制、异常处理以及异步请求和自定义拦截器等内容,希望能帮助开发者在Java项目中熟练运用Apache HttpClient进行高效的网络请求开发。