概述
日常工作中,我们经常会有发送 HTTP 网络请求的需求,概括下我们常见的发送 HTTP 请求的需求内容:
- 可以发送基本的 GET/POST/PUT/DELETE 等请求;
- HTTP请求,可以附带认证,包括基本的 用户名/密码 认证,以及 Bearer Token 认证;
- 请求可以自定义 超时时间;
- HTTP请求可以带参数,也可以不带参数;
- HTTP请求返回结果,可以直接传入一个 Class,这样结果就不用二次解析;
- 请求的路径可以是 url,也可以是 Uri;
针对以上常见的 HTTP 请求,在 HttpClient 的基础上做了二次封装,可以直接简单、高效地发送HTTP请求。
本文所使用的的 HttpClient 版本为 4.5.3,pom依赖如下:
1
2
3
4
5
|
< dependency >
< groupId >org.apache.httpcomponents</ groupId >
< artifactId >httpclient</ artifactId >
< version >4.5.3</ version >
</ dependency >
|
认证方式
HTTP请求中,常用的认证方式包括:
- 用户名 + 密码 认证
- Bearer Token 认证
其实这些认证的本质,都是通过在 HTTP Request Header 中,添加固定的参数,如下格式:
1
|
Authorization: token字符串
|
上面的Authorization 就是 HTTP Header 的 key,而 token字符串 就是具体的认证方式中需要传递的参数。
我们将所有的认证方式,都抽象为 Auth 类,并定义方法 getAuth 方法,由具体的子类去实现,返回自定义认证方式中所需要的token字符串。
基础认证Auth
1
2
3
4
|
public interface Auth {
String getAuth();
}
|
用户名密码认证
BasicAuth,用于做用户名和密码认证,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public class BasicAuth implements Auth {
private String username;
private String password;
public BasicAuth(String username, String password) {
this .username = username;
this .password = password;
}
@Override
public String getAuth() {
String auth = String.format( "%s:%s" , this .username, this .password);
byte [] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1));
return "Basic " + new String(encodedAuth);
}
}
|
Bearer Token 认证
BearerAuth,用于做 Bearer Token认证,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class BearerAuth implements Auth {
private String token;
public BearerAuth(String token) {
this .token = token;
}
@Override
public String getAuth() {
return "Bearer " + this .token;
}
}
|
上面介绍了两种常用的认证方式,如果有其他的认证方式,实现 Auth 接口的 getAuth 方法即可。
这个 Auth 我们会在真正发送 HTTP 请求时用到。
配置超时
HttpClient中,通过 setDefaultRequestConfig 来设置请求的参数配置,包括请求超时时间等。
生成 RequestConfig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
/**
* 设置 HTTP 请求超时时间
*
* @param connectTimeout tcp 连接超时时间
* @param readTimeout 读取数据超时时间
* @return
*/
private RequestConfig getRequestConfig( int connectTimeout, int readTimeout) {
return RequestConfig.custom()
.setConnectTimeout(connectTimeout)
.setConnectionRequestTimeout(connectTimeout)
.setSocketTimeout(readTimeout)
.build();
}
|
设置超时时间
1
2
3
|
HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.build();
|
到这里,HttpClient所需要做的一些配置,基本就结束了,下面将展示完整的代码示例。
完整代码 HttpRequestClient
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
|
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.http.HttpMethod;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
/**
* @author wxweven
*/
@Slf4j
public class HttpRequestClient {
// 默认 连接/读取数据 超时时间都是 10s
private static final int DEFAULT_CONNECT_TIMEOUT = 10_000;
private static final int DEFAULT_READ_TIMEOUT = 10_000;
private static final Gson GSON = new Gson();
private Auth auth;
private HttpClient httpClient;
// 用户名密码认证,默认的超时时间(10s)
public HttpRequestClient(String username, String password) {
this (username, password,
DEFAULT_CONNECT_TIMEOUT,
DEFAULT_READ_TIMEOUT
);
}
// 用户名密码认证,自定义超时时间
public HttpRequestClient(String username, String password,
int connectTimeout, int readTimeout) {
this .auth = new BasicAuth(username, password);
this .httpClient = HttpClientBuilder.create()
.setDefaultRequestConfig(getRequestConfig(connectTimeout, readTimeout))
.build();
}
// BearerToken 认证,默认的超时时间(10s)
public HttpRequestClient(String bearerToken) {
this (bearerToken,
DEFAULT_CONNECT_TIMEOUT,
DEFAULT_READ_TIMEOUT
);
}
// BearerToken 认证,自定义超时时间
public HttpRequestClient(String bearerToken,
int connectTimeout, int readTimeout) {
this .auth = new BearerAuth(bearerToken);
this .httpClient = HttpClientBuilder.create()
.setDefaultRequestConfig(getRequestConfig(connectTimeout, readTimeout))
.build();
}
/**
* 设置 HTTP 请求超时时间
*
* @param connectTimeout tcp 连接超时时间
* @param readTimeout 读取数据超时时间
* @return
*/
private RequestConfig getRequestConfig( int connectTimeout, int readTimeout) {
return RequestConfig.custom()
.setConnectTimeout(connectTimeout)
.setConnectionRequestTimeout(connectTimeout)
.setSocketTimeout(readTimeout)
.build();
}
/**
* 发送 GET 请求,不带参数
*
* @param url
* @return
*/
public String doGet(String url) {
return doGet(url, new HashMap<>());
}
/**
* 发送 GET 请求,不带参数
*
* @param uri
* @return
*/
public String doGet(URI uri) {
return doGet(uri, new HashMap<>());
}
/**
* 发送 GET 请求,K-V 形式参数
*
* @param url
* @param params
* @return
*/
public String doGet(String url, Map<String, String> params) {
RequestBuilder reqBuilder = RequestBuilder.get(url);
return doGet(reqBuilder, params);
}
/**
* 发送 GET 请求,K-V 形式参数
*
* @param uri
* @param params
* @return
*/
public String doGet(URI uri, Map<String, String> params) {
RequestBuilder reqBuilder = RequestBuilder.get(uri);
return doGet(reqBuilder, params);
}
public String doGet(RequestBuilder reqBuilder, Map<String, String> params) {
reqBuilder.addHeader(HttpHeaders.AUTHORIZATION, auth.getAuth());
for (Map.Entry<String, String> entry : params.entrySet()) {
reqBuilder.addParameter(entry.getKey(), entry.getValue());
}
try {
HttpResponse resp = httpClient.execute(reqBuilder.build());
return EntityUtils.toString(resp.getEntity(), StandardCharsets.UTF_8);
} catch (IOException e) {
log.error( "doGet 异常: reqBuilder={}, params={}" , reqBuilder, params, e);
return null ;
}
}
/***
* 发送 GET 请求,不带参数,返回指定类型的 class
* @param url 请求的 url
* @param responseType 返回类型
* @param <T>
* @return
*/
public <T> T getForObject(String url, Class<T> responseType) {
RequestBuilder reqBuilder = RequestBuilder.get(url);
return getForObject(reqBuilder, responseType);
}
/***
* 发送 GET 请求,不带参数,返回指定类型的 class
* @param uri 请求的 uri
* @param responseType 返回类型
* @param <T>
* @return
*/
public <T> T getForObject(URI uri, Class<T> responseType) {
RequestBuilder reqBuilder = RequestBuilder.get(uri);
return getForObject(reqBuilder, responseType);
}
public <T> T getForObject(RequestBuilder reqBuilder, Class<T> responseType) {
reqBuilder.addHeader(HttpHeaders.AUTHORIZATION, auth.getAuth());
try {
HttpResponse resp = httpClient.execute(reqBuilder.build());
String result = EntityUtils.toString(resp.getEntity(), StandardCharsets.UTF_8);
return GSON.fromJson(result, responseType);
} catch (IOException e) {
log.error( "getForObject 异常: reqBuilder={}, responseType={}" , reqBuilder, responseType, e);
return null ;
}
}
/**
* 发送 POST 请求,JSON 形式
*
* @param url
* @param json json字符串
* @return
*/
public String doPost(String url, String json) {
try {
HttpResponse resp = this .exchange(HttpMethod.POST, url, json);
return EntityUtils.toString(resp.getEntity(), StandardCharsets.UTF_8);
} catch (IOException e) {
log.error( "doPost 异常: url={}, json={}" , url, json, e);
return null ;
}
}
/**
* 发送 POST 请求,JSON 形式,返回 HttpResponse
*
* @param url
* @param json json字符串
* @return
*/
public HttpResponse doPostResp(String url, String json) {
return this .exchange(HttpMethod.POST, url, json);
}
/**
* 发送 PUT 请求,JSON 形式
*
* @param url
* @param json json字符串
* @return
*/
public HttpResponse doPut(String url, String json) {
return this .exchange(HttpMethod.PUT, url, json);
}
/**
* 发送 PUT 请求,JSON 形式
*
* @param url
* @param json json字符串
* @return
*/
public HttpResponse doDelete(String url, String json) {
return this .exchange(HttpMethod.DELETE, url, json);
}
public HttpResponse exchange(HttpMethod method, String url, String json) {
RequestBuilder reqBuilder = RequestBuilder.create(method.toString())
.setUri(url)
.addHeader(HttpHeaders.AUTHORIZATION, auth.getAuth())
.addHeader( "Accept" , ContentType.APPLICATION_JSON.toString())
.addHeader( "Content-type" , ContentType.APPLICATION_JSON.toString());
if (StringUtils.isNotBlank(json)) {
reqBuilder.setEntity( new StringEntity(json, ContentType.APPLICATION_JSON));
}
try {
return httpClient.execute(reqBuilder.build());
} catch (IOException e) {
log.error( "doPost 异常: url={}, json={}" , url, json, e);
return null ;
}
}
}
|
到此这篇关于Java 使用 HttpClient 发送 GET请求和 POST请求的文章就介绍到这了,更多相关Java HttpClient GET请求和 POST请求内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://juejin.cn/post/6998826369819869215