Http協議的重要性相信不用我多說了,HttpClient相比傳統JDK自帶的URLConnection,增加了易用性和靈活性(具體區別,日后我們再討論),它不僅是客戶端發送Http請求變得容易,而且也方便了開發人員測試接口(基于Http協議的),即提高了開發的效率,也方便提高代碼的健壯性。因此熟練掌握HttpClient是很重要的必修內容,掌握HttpClient后,相信對于Http協議的了解會更加深入。
一、簡介
HttpClient是Apache Jakarta Common下的子項目,用來提供高效的、最新的、功能豐富的支持HTTP協議的客戶端編程工具包,并且它支持HTTP協議最新的版本和建議。HttpClient已經應用在很多的項目中,比如Apache Jakarta上很著名的另外兩個開源項目Cactus和HTMLUnit都使用了HttpClient。
下載地址: http://hc.apache.org/downloads.cgi
二、特性
1. 基于標準、純凈的java語言。實現了Http1.0和Http1.1
2. 以可擴展的面向對象的結構實現了Http全部的方法(GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE)。
3. 支持HTTPS協議。
4. 通過Http代理建立透明的連接。
5. 利用CONNECT方法通過Http代理建立隧道的https連接。
6. Basic, Digest, NTLMv1, NTLMv2, NTLM2 Session, SNPNEGO/Kerberos認證方案。
7. 插件式的自定義認證方案。
8. 便攜可靠的套接字工廠使它更容易的使用第三方解決方案。
9. 連接管理器支持多線程應用。支持設置最大連接數,同時支持設置每個主機的最大連接數,發現并關閉過期的連接。
10. 自動處理Set-Cookie中的Cookie。
11. 插件式的自定義Cookie策略。
12. Request的輸出流可以避免流中內容直接緩沖到socket服務器。
13. Response的輸入流可以有效的從socket服務器直接讀取相應內容。
14. 在http1.0和http1.1中利用KeepAlive保持持久連接。
15. 直接獲取服務器發送的response code和 headers。
16. 設置連接超時的能力。
17. 實驗性的支持http1.1 response caching。
18. 源代碼基于Apache License 可免費獲取。
三、使用方法
使用HttpClient發送請求、接收響應很簡單,一般需要如下幾步即可。
1. 創建HttpClient對象。
2. 創建請求方法的實例,并指定請求URL。如果需要發送GET請求,創建HttpGet對象;如果需要發送POST請求,創建HttpPost對象。
3. 如果需要發送請求參數,可調用HttpGet、HttpPost共同的setParams(HetpParams params)方法來添加請求參數;對于HttpPost對象而言,也可調用setEntity(HttpEntity entity)方法來設置請求參數。
4. 調用HttpClient對象的execute(HttpUriRequest request)發送請求,該方法返回一個HttpResponse。
5. 調用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可獲取服務器的響應頭;調用HttpResponse的getEntity()方法可獲取HttpEntity對象,該對象包裝了服務器的響應內容。程序可通過該對象獲取服務器的響應內容。
6. 釋放連接。無論執行方法是否成功,都必須釋放連接
四、實例
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
253
254
255
256
257
258
259
260
261
262
263
264
265
|
package com.test; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.List; import javax.net.ssl.SSLContext; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.ParseException; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.entity.ContentType; 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.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.junit.Test; public class HttpClientTest { @Test public void jUnitTest() { get(); } /** * HttpClient連接SSL */ public void ssl() { CloseableHttpClient httpclient = null ; try { KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); FileInputStream instream = new FileInputStream( new File( "d:\\tomcat.keystore" )); try { // 加載keyStore d:\\tomcat.keystore trustStore.load(instream, "123456" .toCharArray()); } catch (CertificateException e) { e.printStackTrace(); } finally { try { instream.close(); } catch (Exception ignore) { } } // 相信自己的CA和所有自簽名的證書 SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build(); // 只允許使用TLSv1協議 SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null , SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); // 創建http請求(get方式) HttpGet httpget = new HttpGet( "https://localhost:8443/myDemo/Ajax/serivceJ.action" ); System.out.println( "executing request" + httpget.getRequestLine()); CloseableHttpResponse response = httpclient.execute(httpget); try { HttpEntity entity = response.getEntity(); System.out.println( "----------------------------------------" ); System.out.println(response.getStatusLine()); if (entity != null ) { System.out.println( "Response content length: " + entity.getContentLength()); System.out.println(EntityUtils.toString(entity)); EntityUtils.consume(entity); } } finally { response.close(); } } catch (ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyStoreException e) { e.printStackTrace(); } finally { if (httpclient != null ) { try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * post方式提交表單(模擬用戶登錄請求) */ public void postForm() { // 創建默認的httpClient實例. CloseableHttpClient httpclient = HttpClients.createDefault(); // 創建httppost HttpPost httppost = new HttpPost( "http://localhost:8080/myDemo/Ajax/serivceJ.action" ); // 創建參數隊列 List<namevaluepair> formparams = new ArrayList<namevaluepair>(); formparams.add( new BasicNameValuePair( "username" , "admin" )); formparams.add( new BasicNameValuePair( "password" , "123456" )); UrlEncodedFormEntity uefEntity; try { uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8" ); httppost.setEntity(uefEntity); System.out.println( "executing request " + httppost.getURI()); CloseableHttpResponse response = httpclient.execute(httppost); try { HttpEntity entity = response.getEntity(); if (entity != null ) { System.out.println( "--------------------------------------" ); System.out.println( "Response content: " + EntityUtils.toString(entity, "UTF-8" )); System.out.println( "--------------------------------------" ); } } finally { response.close(); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 關閉連接,釋放資源 try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 發送 post請求訪問本地應用并根據傳遞參數不同返回不同結果 */ public void post() { // 創建默認的httpClient實例. CloseableHttpClient httpclient = HttpClients.createDefault(); // 創建httppost HttpPost httppost = new HttpPost( "http://localhost:8080/myDemo/Ajax/serivceJ.action" ); // 創建參數隊列 List<namevaluepair> formparams = new ArrayList<namevaluepair>(); formparams.add( new BasicNameValuePair( "type" , "house" )); UrlEncodedFormEntity uefEntity; try { uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8" ); httppost.setEntity(uefEntity); System.out.println( "executing request " + httppost.getURI()); CloseableHttpResponse response = httpclient.execute(httppost); try { HttpEntity entity = response.getEntity(); if (entity != null ) { System.out.println( "--------------------------------------" ); System.out.println( "Response content: " + EntityUtils.toString(entity, "UTF-8" )); System.out.println( "--------------------------------------" ); } } finally { response.close(); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 關閉連接,釋放資源 try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 發送 get請求 */ public void get() { CloseableHttpClient httpclient = HttpClients.createDefault(); try { // 創建httpget. HttpGet httpget = new HttpGet( "http://www.baidu.com/" ); System.out.println( "executing request " + httpget.getURI()); // 執行get請求. CloseableHttpResponse response = httpclient.execute(httpget); try { // 獲取響應實體 HttpEntity entity = response.getEntity(); System.out.println( "--------------------------------------" ); // 打印響應狀態 System.out.println(response.getStatusLine()); if (entity != null ) { // 打印響應內容長度 System.out.println( "Response content length: " + entity.getContentLength()); // 打印響應內容 System.out.println( "Response content: " + EntityUtils.toString(entity)); } System.out.println( "------------------------------------" ); } finally { response.close(); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 關閉連接,釋放資源 try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 上傳文件 */ public void upload() { CloseableHttpClient httpclient = HttpClients.createDefault(); try { HttpPost httppost = new HttpPost( "http://localhost:8080/myDemo/Ajax/serivceFile.action" ); FileBody bin = new FileBody( new File( "F:\\image\\sendpix0.jpg" )); StringBody comment = new StringBody( "A binary file of some kind" , ContentType.TEXT_PLAIN); HttpEntity reqEntity = MultipartEntityBuilder.create().addPart( "bin" , bin).addPart( "comment" , comment).build(); httppost.setEntity(reqEntity); System.out.println( "executing request " + httppost.getRequestLine()); CloseableHttpResponse response = httpclient.execute(httppost); try { System.out.println( "----------------------------------------" ); System.out.println(response.getStatusLine()); HttpEntity resEntity = response.getEntity(); if (resEntity != null ) { System.out.println( "Response content length: " + resEntity.getContentLength()); } EntityUtils.consume(resEntity); } finally { response.close(); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } } </namevaluepair></namevaluepair> </namevaluepair></namevaluepair> |
本實例是采用HttpClient4.3最新版本。該版本與之前的代碼寫法風格相差較大,大家多留意下。