spring 集成 httpclient

前言

httpclient 介绍

The Hyper-Text Transfer Protocol (HTTP) is perhaps the most significant protocol used on the Internet today. Web services, network-enabled appliances and the growth of network computing continue to expand the role of the HTTP protocol beyond user-driven web browsers, while increasing the number of applications that require HTTP support.
Although the java.net package provides basic functionality for accessing resources via HTTP, it doesn’t provide the full flexibility or functionality needed by many applications. HttpClient seeks to fill this void by providing an efficient, up-to-date, and feature-rich package implementing the client side of the most recent HTTP standards and recommendations.
Designed for extension while providing robust support for the base HTTP protocol, HttpClient may be of interest to anyone building HTTP-aware client applications such as web browsers, web service clients, or systems that leverage or extend the HTTP protocol for distributed communication.

准备工作

在pom.xml文件中增加以下依赖

1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>

书写配置类

用@Configuration注解该类,等价与XML中配置beans;用@Bean标注方法等价于XML中配置bean。

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
@Configuration
public class HttpConfiguration {
@Bean
public LayeredConnectionSocketFactory sslSF() {
LayeredConnectionSocketFactory sslSF = null;
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
//信任任何链接
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
return true;
}
}).build();
return new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return sslSF;
}
@Bean
public Registry<ConnectionSocketFactory> registryBuilder() {
return RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslSF())
.register("http", new PlainConnectionSocketFactory())
.build();
}
@Bean
public PoolingHttpClientConnectionManager connectionManager() {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registryBuilder());
connectionManager.setMaxTotal(500);
connectionManager.setDefaultMaxPerRoute(500);
return connectionManager;
}
@Bean
public CloseableHttpClient httpClient() {
return HttpClients.custom()
.setConnectionManager(connectionManager())
.build();
}
@Bean
public RequestConfig requestConfig() {
return RequestConfig.custom()
.setConnectTimeout(10000)
.setConnectionRequestTimeout(500)
.setSocketTimeout(10000)
.build();
}
@Bean(destroyMethod = "shutdown")
public IdleConnectionEvictor idleConnectionEvictor() {
return new IdleConnectionEvictor(connectionManager());
}
}

定期清理无效的http连接

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
public class IdleConnectionEvictor extends Thread {
private final HttpClientConnectionManager connMgr;
private volatile boolean shutdown;
public IdleConnectionEvictor(HttpClientConnectionManager connMgr) {
super();
this.connMgr = connMgr;
// 启动当前线程
this.start();
}
@Override
public void run() {
try {
while (!shutdown) {
synchronized (this) {
wait(5000);
// 关闭失效的连接
connMgr.closeExpiredConnections();
}
}
} catch (InterruptedException ex) {
// 结束
}
}
public void shutdown() {
shutdown = true;
synchronized (this) {
notifyAll();
}
}
}

工具类

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
@Component
public class HttpClientUtil {
private static final Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
@Resource
private CloseableHttpClient httpClient;
@Resource
private RequestConfig requestConfig;
/**
* get
*
* @param url 请求的url
* @param queries 请求的参数,在浏览器?后面的数据,没有可以传null
* @return
*/
public String get(String url, Map<String, String> queries) {
String responseBody = "";
//支持https
StringBuffer sb = new StringBuffer(url);
if (queries != null && queries.keySet().size() > 0) {
boolean firstFlag = true;
Iterator iterator = queries.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry<String, String>) iterator.next();
if (firstFlag) {
sb.append("?" + entry.getKey() + "=" + entry.getValue());
firstFlag = false;
} else {
sb.append("&" + entry.getKey() + "=" + entry.getValue());
}
}
}
HttpGet httpGet = new HttpGet(sb.toString());
//设置超时
httpGet.setConfig(this.requestConfig);
//请求数据
CloseableHttpResponse response = null;
try {
response = this.httpClient.execute(httpGet);
int status = response.getStatusLine().getStatusCode();
if (status == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
responseBody = EntityUtils.toString(entity);
// EntityUtils.consume(response.getEntity()); //会自动释放连接
}
} catch (Exception ex) {
logger.error("http error >> ex = {}", ExceptionUtils.getStackTrace(ex));
} finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
logger.error("http close error >> ex = {}", ExceptionUtils.getStackTrace(e));
}
}
}
return responseBody;
}
/**
* get
*
* @param url 请求的url
* @param queries 请求的参数,在浏览器?后面的数据,没有可以传null
* @return
*/
public File getFile(String url, Map<String, String> queries, File file) {
//支持https
StringBuffer sb = new StringBuffer(url);
if (queries != null && queries.keySet().size() > 0) {
boolean firstFlag = true;
Iterator iterator = queries.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry<String, String>) iterator.next();
if (firstFlag) {
sb.append("?" + entry.getKey() + "=" + entry.getValue());
firstFlag = false;
} else {
sb.append("&" + entry.getKey() + "=" + entry.getValue());
}
}
}
HttpGet httpGet = new HttpGet(sb.toString());
//设置超时
httpGet.setConfig(this.requestConfig);
//请求数据
CloseableHttpResponse response = null;
try {
response = this.httpClient.execute(httpGet);
int status = response.getStatusLine().getStatusCode();
if (status == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
BufferedInputStream bis = new BufferedInputStream(entity.getContent());
if (bis.available() < 1024) {
bis.close();
return null;
}
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[1024];
int size = 0;
while ((size = bis.read(buf)) != -1) {
fos.write(buf, 0, size);
}
fos.close();
bis.close();
}
} catch (Exception ex) {
logger.error("http error >> ex = {}", ExceptionUtils.getStackTrace(ex));
file.delete();
return null;
} finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
logger.error("http close error >> ex = {}", ExceptionUtils.getStackTrace(e));
}
}
}
return file;
}
/**
* post
*
* @param url 请求的url
* @param queries 请求的参数,在浏览器?后面的数据,没有可以传null
* @param params post form 提交的参数
* @return
*/
public String post(String url, Map<String, String> queries, Map<String, String> params) {
String responseBody = "";
StringBuffer sb = new StringBuffer(url);
if (queries != null && queries.keySet().size() > 0) {
boolean firstFlag = true;
Iterator iterator = queries.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = (Map.Entry<String, String>) iterator.next();
if (firstFlag) {
sb.append("?" + entry.getKey() + "=" + entry.getValue());
firstFlag = false;
} else {
sb.append("&" + entry.getKey() + "=" + entry.getValue());
}
}
}
//指定url,和http方式
HttpPost httpPost = new HttpPost(sb.toString());
httpPost.setConfig(this.requestConfig);
//添加参数
List<NameValuePair> nvps = new ArrayList<>();
if (params != null && params.keySet().size() > 0) {
for (String key : params.keySet()) {
nvps.add(new BasicNameValuePair(key, params.get(key)));
}
}
httpPost.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8));
//请求数据
CloseableHttpResponse response = null;
try {
response = this.httpClient.execute(httpPost);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
responseBody = EntityUtils.toString(entity);
// EntityUtils.consume(response.getEntity()); //会自动释放连接
}
} catch (IOException ex) {
logger.error("http error >> ex = {}", ExceptionUtils.getStackTrace(ex));
} finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
logger.error("http close error >> ex = {}", ExceptionUtils.getStackTrace(e));
}
}
}
return responseBody;
}
/**
* post
*
* @param url 请求的url
* @param data post json 提交的参数
* @return
*/
public String post(String url, String data) {
String responseBody = "";
StringBuffer sb = new StringBuffer(url);
//指定url,和http方式
HttpPost httpPost = new HttpPost(sb.toString());
httpPost.setConfig(this.requestConfig);
//设置类型
StringEntity se = new StringEntity(data, "utf-8");
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
httpPost.setEntity(se);
//请求数据
CloseableHttpResponse response = null;
try {
response = this.httpClient.execute(httpPost);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
responseBody = EntityUtils.toString(entity);
}
} catch (IOException ex) {
logger.error("http post error >> ex = {}", ExceptionUtils.getStackTrace(ex));
} finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
logger.error("http post close error >> ex = {}", ExceptionUtils.getStackTrace(e));
}
}
}
return responseBody;
}
}

使用方法

1
2
@Resource
private HttpClientUtil httpClientUtil;
Enjoy it ? Donate me !
欣赏此文?求鼓励,求支持!