Skip to content

Commit 3092e34

Browse files
committed
feat: Apache HttpClient 5 使用详细教程(https://www.wdbyte.com/tool/httpclient5.html)
1 parent f0d82dc commit 3092e34

17 files changed

Lines changed: 991 additions & 1 deletion

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ Java 版本任你发,我用 Java 8 。但是多学点这种装x技巧总没错
164164
>出处:孔子《论语》
165165
166166
一款好用的工具,不仅可以装X,更可以让你事半功倍,准时下班。
167-
167+
- [Apache HttpClient 5 使用详细教程](https://www.wdbyte.com/tool/httpclient5.html)
168168
- [Jackson 解析 JSON 详细教程](https://www.wdbyte.com/tool/jackson.html)
169169
- [Java 反编译工具的使用与对比分析](https://www.wdbyte.com/2021/05/java-decompiler/)
170170
- [可以Postman,也可以cURL.进来领略下cURL的独门绝技](https://www.wdbyte.com/2020/06/tool/curl/)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## tool-java-apache-httpclient
2+
当前模块包含 Apache HttpClient 5 相关代码
3+
4+
### 相关文章
5+
- [Apache HttpClient 5 使用详细教程](https://www.wdbyte.com/tool/httpclient5.html)
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
package com.wdbyte.httpclient;
2+
3+
import java.io.IOException;
4+
import java.nio.CharBuffer;
5+
import java.util.concurrent.CountDownLatch;
6+
import java.util.concurrent.ExecutionException;
7+
import java.util.concurrent.Future;
8+
9+
import org.apache.hc.client5.http.async.methods.AbstractCharResponseConsumer;
10+
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
11+
import org.apache.hc.client5.http.async.methods.SimpleHttpRequests;
12+
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
13+
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
14+
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
15+
import org.apache.hc.core5.concurrent.FutureCallback;
16+
import org.apache.hc.core5.http.ContentType;
17+
import org.apache.hc.core5.http.HttpException;
18+
import org.apache.hc.core5.http.HttpResponse;
19+
import org.apache.hc.core5.http.nio.AsyncRequestProducer;
20+
import org.apache.hc.core5.http.nio.support.AsyncRequestBuilder;
21+
22+
/**
23+
* HttpClient 5 异步请求
24+
* @author https://www.wdbyte.com
25+
* @date 2022/06/25
26+
*/
27+
public class HttpClient5Async {
28+
29+
public static void main(String[] args) {
30+
getAsync1("http://httpbin.org/get");
31+
getAsync2("http://httpbin.org/get");
32+
getAsync3("http://httpbin.org/get");
33+
}
34+
35+
/**
36+
* 异步请求
37+
*
38+
* @param url
39+
* @return
40+
*/
41+
public static String getAsync1(String url) {
42+
try (CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault()) {
43+
// 开始 http clinet
44+
httpclient.start();
45+
// 执行请求
46+
SimpleHttpRequest request1 = SimpleHttpRequests.get(url);
47+
Future<SimpleHttpResponse> future = httpclient.execute(request1, null);
48+
// 等待直到返回完毕
49+
SimpleHttpResponse response1 = future.get();
50+
System.out.println("getAsync1:" + request1.getRequestUri() + "->" + response1.getCode());
51+
} catch (IOException | ExecutionException | InterruptedException e) {
52+
throw new RuntimeException(e);
53+
}
54+
return null;
55+
}
56+
57+
/**
58+
* 异步请求,根据响应情况回调
59+
*
60+
* @param url
61+
* @return
62+
*/
63+
public static String getAsync2(String url) {
64+
try (CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault()) {
65+
// 开始 http clinet
66+
httpclient.start();
67+
// 根据请求响应情况进行回调操作
68+
CountDownLatch latch = new CountDownLatch(1);
69+
SimpleHttpRequest request = SimpleHttpRequests.get(url);
70+
httpclient.execute(request, new FutureCallback<SimpleHttpResponse>() {
71+
@Override
72+
public void completed(SimpleHttpResponse response2) {
73+
latch.countDown();
74+
System.out.println("getAsync2:" + request.getRequestUri() + "->" + response2.getCode());
75+
}
76+
77+
@Override
78+
public void failed(Exception ex) {
79+
latch.countDown();
80+
System.out.println("getAsync2:" + request.getRequestUri() + "->" + ex);
81+
}
82+
83+
@Override
84+
public void cancelled() {
85+
latch.countDown();
86+
System.out.println("getAsync2:" + request.getRequestUri() + " cancelled");
87+
}
88+
89+
});
90+
latch.await();
91+
} catch (IOException | InterruptedException e) {
92+
throw new RuntimeException(e);
93+
}
94+
return null;
95+
}
96+
97+
/**
98+
* 异步请求,对响应流做点什么
99+
*
100+
* @param url
101+
* @return
102+
*/
103+
public static String getAsync3(String url) {
104+
try (CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault()) {
105+
// 开始 http clinet
106+
httpclient.start();
107+
// 根据请求响应情况进行回调操作
108+
SimpleHttpRequest request = SimpleHttpRequests.get(url);
109+
110+
CountDownLatch latch = new CountDownLatch(1);
111+
AsyncRequestProducer producer = AsyncRequestBuilder.get("http://httpbin.org/get").build();
112+
AbstractCharResponseConsumer<HttpResponse> consumer3 = new AbstractCharResponseConsumer<HttpResponse>() {
113+
114+
HttpResponse response;
115+
116+
@Override
117+
protected void start(HttpResponse response, ContentType contentType) throws HttpException, IOException {
118+
System.out.println("getAsync3: 开始响应....");
119+
this.response = response;
120+
}
121+
122+
@Override
123+
protected int capacityIncrement() {
124+
return Integer.MAX_VALUE;
125+
}
126+
127+
@Override
128+
protected void data(CharBuffer data, boolean endOfStream) throws IOException {
129+
System.out.println("getAsync3: 收到数据....");
130+
// Do something useful
131+
}
132+
133+
@Override
134+
protected HttpResponse buildResult() throws IOException {
135+
System.out.println("getAsync3: 接收完毕...");
136+
return response;
137+
}
138+
139+
@Override
140+
public void releaseResources() {
141+
}
142+
143+
};
144+
httpclient.execute(producer, consumer3, new FutureCallback<HttpResponse>() {
145+
146+
@Override
147+
public void completed(HttpResponse response) {
148+
latch.countDown();
149+
System.out.println("getAsync3: "+request.getRequestUri() + "->" + response.getCode());
150+
}
151+
152+
@Override
153+
public void failed(Exception ex) {
154+
latch.countDown();
155+
System.out.println("getAsync3: "+request.getRequestUri() + "->" + ex);
156+
}
157+
158+
@Override
159+
public void cancelled() {
160+
latch.countDown();
161+
System.out.println("getAsync3: "+request.getRequestUri() + " cancelled");
162+
}
163+
164+
});
165+
latch.await();
166+
} catch (IOException | InterruptedException e) {
167+
throw new RuntimeException(e);
168+
}
169+
return null;
170+
171+
}
172+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package com.wdbyte.httpclient;
2+
3+
import org.apache.hc.client5.http.auth.AuthScope;
4+
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
5+
import org.apache.hc.client5.http.classic.methods.HttpGet;
6+
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
7+
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
8+
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
9+
import org.apache.hc.client5.http.impl.classic.HttpClients;
10+
import org.apache.hc.core5.http.io.entity.EntityUtils;
11+
12+
/**
13+
* 一个简单的示例,它使用HttpClient执行HTTP请求;
14+
* 一个需要进行用户身份验证的目标站点。
15+
* Basic Authorization
16+
*
17+
* GET /basic-auth/user/passwd HTTP/1.1
18+
* Accept-Encoding: gzip, x-gzip, deflate
19+
* Host: httpbin.org
20+
* Connection: keep-alive
21+
* User-Agent: Apache-HttpClient/5.1.3 (Java/1.8.0_151)
22+
*
23+
* HTTP/1.1 401 UNAUTHORIZED
24+
* Date: Sat, 06 Aug 2022 08:25:33 GMT
25+
* Content-Length: 0
26+
* Connection: keep-alive
27+
* Server: gunicorn/19.9.0
28+
* WWW-Authenticate: Basic realm="Fake Realm"
29+
* Access-Control-Allow-Origin: *
30+
* Access-Control-Allow-Credentials: true
31+
*
32+
* GET /basic-auth/user/passwd HTTP/1.1
33+
* Host: httpbin.org
34+
* Connection: keep-alive
35+
* User-Agent: Apache-HttpClient/5.1.3 (Java/1.8.0_151)
36+
* Authorization: Basic dXNlcjpwYXNzd2Q=
37+
*
38+
* HTTP/1.1 200 OK
39+
* Date: Sat, 06 Aug 2022 08:25:33 GMT
40+
* Content-Type: application/json
41+
* Content-Length: 47
42+
* Connection: keep-alive
43+
* Server: gunicorn/19.9.0
44+
* Access-Control-Allow-Origin: *
45+
* Access-Control-Allow-Credentials: true
46+
*
47+
* {
48+
* "authenticated": true,
49+
* "user": "user"
50+
* }
51+
*/
52+
public class HttpClient5BasicAuthentication {
53+
54+
public static void main(final String[] args) throws Exception {
55+
final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
56+
credsProvider.setCredentials(
57+
new AuthScope("httpbin.org", 80),
58+
new UsernamePasswordCredentials("admin", "123456".toCharArray()));
59+
try (final CloseableHttpClient httpclient = HttpClients.custom()
60+
.setDefaultCredentialsProvider(credsProvider)
61+
.build()) {
62+
final HttpGet httpget = new HttpGet("http://httpbin.org/basic-auth/admin/123456");
63+
64+
System.out.println("执行请求" + httpget.getMethod() + " " + httpget.getUri());
65+
try (final CloseableHttpResponse response = httpclient.execute(httpget)) {
66+
System.out.println("----------------------------------------");
67+
System.out.println(response.getCode() + " " + response.getReasonPhrase());
68+
System.out.println(EntityUtils.toString(response.getEntity()));
69+
}
70+
}
71+
}
72+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.wdbyte.httpclient;
2+
3+
import org.apache.hc.client5.http.classic.methods.HttpGet;
4+
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
5+
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
6+
import org.apache.hc.client5.http.impl.classic.HttpClients;
7+
8+
/**
9+
* 这个案例展示了如何中止一个HTTP方法之前正常完成。;
10+
*/
11+
public class HttpClient5CancleMethod {
12+
13+
public static void main(final String[] args) throws Exception {
14+
try (final CloseableHttpClient httpclient = HttpClients.createDefault()) {
15+
final HttpGet httpget = new HttpGet("http://httpbin.org/get");
16+
17+
System.out.println("执行请求 " + httpget.getMethod() + " " + httpget.getUri());
18+
try (final CloseableHttpResponse response = httpclient.execute(httpget)) {
19+
System.out.println("----------------------------------------");
20+
System.out.println(response.getCode() + " " + response.getReasonPhrase());
21+
// 不像读取结果,直接中止
22+
httpget.cancel();
23+
}
24+
}
25+
}
26+
27+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.wdbyte.httpclient;
2+
3+
import java.io.File;
4+
import java.io.FileInputStream;
5+
6+
import org.apache.hc.client5.http.classic.methods.HttpPost;
7+
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
8+
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
9+
import org.apache.hc.client5.http.impl.classic.HttpClients;
10+
import org.apache.hc.core5.http.ContentType;
11+
import org.apache.hc.core5.http.io.entity.EntityUtils;
12+
import org.apache.hc.core5.http.io.entity.FileEntity;
13+
import org.apache.hc.core5.http.io.entity.InputStreamEntity;
14+
15+
/**
16+
* 加载数据流作为 POST 请求参数
17+
*/
18+
public class HttpClient5ChunkEncodedPost {
19+
20+
public static void main(final String[] args) throws Exception {
21+
String params = "/Users/darcy/params.json";
22+
23+
try (final CloseableHttpClient httpclient = HttpClients.createDefault()) {
24+
final HttpPost httppost = new HttpPost("http://httpbin.org/post");
25+
26+
final InputStreamEntity reqEntity = new InputStreamEntity(new FileInputStream(params), -1,
27+
ContentType.APPLICATION_JSON);
28+
// 也可以使用 FileEntity 的形式
29+
// FileEntity reqEntity = new FileEntity(new File(params), ContentType.APPLICATION_JSON);
30+
31+
httppost.setEntity(reqEntity);
32+
33+
System.out.println("执行请求 " + httppost.getMethod() + " " + httppost.getUri());
34+
try (final CloseableHttpResponse response = httpclient.execute(httppost)) {
35+
System.out.println("----------------------------------------");
36+
System.out.println(response.getCode() + " " + response.getReasonPhrase());
37+
System.out.println(EntityUtils.toString(response.getEntity()));
38+
}
39+
}
40+
}
41+
42+
}

0 commit comments

Comments
 (0)