HttpClient详解

HttpClient:是一个接口

首先需要先创建一个DefaultHttpClient的实例

HttpClient httpClient=new DefaultHttpClient();

发送GET请求:

先创建一个HttpGet对象,传入目标的网络地址,然后调用HttpClient的execute()方法即可:

HttpGet HttpGet=new HttpGet(“http://www.baidu.com”);

httpClient.execute(httpGet);

发送POST请求:

创建一个HttpPost对象,传入目标的网络地址:

HttpPost httpPost=new HttpPost(“http://www.baidu.com”);

通过一个NameValuePair集合来存放待提交的参数,并将这个参数集合传入到一个UrlEncodedFormEntity中,然后调用HttpPost的setEntity()方法将构建好的UrlEncodedFormEntity传入:

List<NameValuePair>params=newArrayList<NameValuePair>();

Params.add(new BasicNameValuePair(“username”,”admin”));

Params.add(new BasicNameValuePair(“password”,”123456”));

UrlEncodedFormEntity entity=newUrlEncodedFormEntity(params,”utf-8”);

httpPost.setEntity(entity);

调用HttpClient的execute()方法,并将HttpPost对象传入即可:

HttpClient.execute(HttpPost);

执行execute()方法之后会返回一个HttpResponse对象,服务器所返回的所有信息就保护在HttpResponse里面.

先取出服务器返回的状态码,如果等于200就说明请求和响应都成功了:

If(httpResponse.getStatusLine().getStatusCode()==200){

//请求和响应都成功了

HttpEntityentity=HttpResponse.getEntity();//调用getEntity()方法获取到一个HttpEntity实例

Stringresponse=EntityUtils.toString(entity,”utf-8”);//用EntityUtils.toString()这个静态方法将HttpEntity转换成字符串,防止服务器返回的数据带有中文,所以在转换的时候将字符集指定成utf-8就可以了

}

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. 释放连接。无论执行方法是否成功,都必须释放连接

四、实例

上传文件实例92-147行

  1 package com.zlzf.channel.common.util;
  2 
  3 import java.io.BufferedReader;
  4 import java.io.ByteArrayOutputStream;
  5 import java.io.DataOutputStream;
  6 import java.io.File;
  7 import java.io.IOException;
  8 import java.io.InputStream;
  9 import java.io.InputStreamReader;
 10 import java.io.OutputStream;
 11 import java.net.URL;
 12 import java.net.URLDecoder;
 13 import java.security.KeyManagementException;
 14 import java.security.NoSuchAlgorithmException;
 15 import java.security.cert.CertificateException;
 16 import java.security.cert.X509Certificate;
 17 import java.util.Iterator;
 18 import java.util.Map;
 19 import java.util.zip.GZIPInputStream;
 20 
 21 import javax.net.ssl.HostnameVerifier;
 22 import javax.net.ssl.HttpsURLConnection;
 23 import javax.net.ssl.SSLContext;
 24 import javax.net.ssl.SSLSession;
 25 import javax.net.ssl.TrustManager;
 26 import javax.net.ssl.X509TrustManager;
 27 
 28 import org.apache.http.HttpEntity;
 29 import org.apache.http.HttpResponse;
 30 import org.apache.http.ParseException;
 31 import org.apache.http.client.ClientProtocolException;
 32 import org.apache.http.client.HttpClient;
 33 import org.apache.http.client.methods.HttpPost;
 34 import org.apache.http.entity.mime.MultipartEntityBuilder;
 35 import org.apache.http.impl.client.HttpClients;
 36 import org.apache.http.util.EntityUtils;
 37 import org.slf4j.Logger;
 38 import org.slf4j.LoggerFactory;
 39 
 40 /**
 41  * @Description: https客户端
 42  * @author syuf
 43  * @date 2017年8月1日 下午4:13:04
 44  */
 45 public class HttpsClientUtil {
 46 
 47     private static final Logger LOG = LoggerFactory.getLogger(HttpsClientUtil.class);
 48     private static final String ENC_UTF8 = "UTF-8";
 49     private static final String ENC_GBK = "GBK";
 50     /**
 51      * 默认的http连接超时时间
 52      */
 53     private final static int DEFAULT_CONN_TIMEOUT = 10000; // 10s
 54     /**
 55      * 默认的http read超时时间
 56      */
 57     private final static int DEFAULT_READ_TIMEOUT = 120000; // 120s
 58 
 59     private static class MyTrustManager implements X509TrustManager {
 60         public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
 61         }
 62 
 63         public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
 64         }
 65 
 66         public X509Certificate[] getAcceptedIssuers() {
 67             return new X509Certificate[] {};
 68         }
 69     }
 70 
 71     private static class TrustAnyHostnameVerifier implements HostnameVerifier {
 72         public boolean verify(String hostname, SSLSession session) {
 73             return true;
 74         }
 75     }
 76     
 77     /**
 78      * @Description: 上传文件  
 79      * @param url 请求地址
 80      * @param fileParamName 上传文件的参数名称
 81      * @param file 文件内容
 82      * @param otherParams 其他 参数
 83      * @return String 应答结果字符串
 84      * @throws  
 85      * @author: syuf
 86      * @date: 2018年3月1日 上午11:32:13
 87       */
 88      public static String uploadFile(String url,String fileParamName,File file, Map<String, String> otherParams) {
 89          return uploadFile(url, fileParamName, file, otherParams, "UTF-8");
 90      }
 91      
 92      /**
 93       * @Description: 上传文件  
 94       * @param url 请求地址
 95       * @param fileParamName 上传文件的参数名称
 96       * @param file 文件内容
 97       * @param otherParams 其他 参数
 98       * @param charset 字符集
 99       * @return String 应答结果字符串
100       * @throws  
101       * @author: syuf
102       * @date: 2018年3月1日 上午11:32:13
103        */
104      public static String uploadFile(String url,String fileParamName,File file, Map<String, String> otherParams,String charset) {
105          HttpEntity resEntity = null;
106          try {
107              SSLContext sc = SSLContext.getInstance("SSL");
108              sc.init(null, new TrustManager[] { new MyTrustManager() }, new java.security.SecureRandom());
109              HttpClient httpClient = HttpClients.custom().setSSLHostnameVerifier(new TrustAnyHostnameVerifier()).setSSLContext(sc).build();
110              HttpPost httpPost = new HttpPost(url);
111              MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
112              for(Map.Entry<String, String> entry : otherParams.entrySet()){
113                  multipartEntityBuilder.addTextBody(entry.getKey(), entry.getValue());
114              }
115              multipartEntityBuilder.addBinaryBody(fileParamName, file);
116              HttpEntity reqEntity = multipartEntityBuilder.build();
117              httpPost.setEntity(reqEntity);
118              HttpResponse response = httpClient.execute(httpPost);  
119              if(response.getStatusLine().getStatusCode() != 200){
120                  LOG.warn("[HttpsClient 上传文件]请求失败,statusCode={}",response.getStatusLine().getStatusCode());
121                  return null;
122              }
123              resEntity = response.getEntity();  
124              if (resEntity == null) { 
125                  LOG.warn("[HttpsClient 上传文件]请求失败,resEntity is null.");
126                  return null;
127              }
128              return EntityUtils.toString(response.getEntity(),charset);
129          } catch (KeyManagementException e) {
130              LOG.error("[HttpsClient 上传文件]NoSuchAlgorithmException.",e);
131          } catch (NoSuchAlgorithmException e) {
132              LOG.error("[HttpsClient 上传文件]NoSuchAlgorithmException.",e);
133          } catch (ClientProtocolException e) {
134              LOG.error("[HttpsClient 上传文件]ClientProtocolException.",e);
135          } catch (ParseException e) {
136              LOG.error("[HttpsClient 上传文件]ParseException.",e);
137          } catch (IOException e) {
138              LOG.error("[HttpsClient 上传文件]IOException.",e);
139          } finally {
140              try {
141                 EntityUtils.consume(resEntity);
142             } catch (IOException e) {
143                 LOG.error("[HttpsClient 上传文件]关闭流异常.",e);
144             }
145          }
146          return null;
147      }
148 
149     /**
150      * @Description: https协议 post zip
151      * @param url 请求地址
152      * @param data 参数字符串
153      * @return String 应答结果字符串
154      * @throws
155      * @author: syuf
156      * @date: 2018年1月15日 下午3:47:03
157      */
158     public static String postZip(String url, String data) {
159         return postZip(url, data, ENC_UTF8);
160     }
161 
162     /**
163      * @Description: https协议 post zip
164      * @param url 请求地址
165      * @param data 参数字符串
166      * @param charset 字符集
167      * @return String 应答结果字符串
168      * @throws
169      * @author: syuf
170      * @date: 2018年1月15日 下午3:50:59
171      */
172     private static String postZip(String url, String data, String charset) {
173         return postZip(url, data, charset, DEFAULT_CONN_TIMEOUT, DEFAULT_READ_TIMEOUT);
174     }
175 
176     /**
177      * @Description: https协议 post zip
178      * @param url 请求地址
179      * @param paramsMap 参数map
180      * @return String 应答结果字符串
181      * @throws
182      * @author: syuf
183      * @date: 2018年1月9日 下午8:37:22
184      */
185     public static String postZip(String url, Map<String, String> paramsMap) {
186         return postZip(url, paramsMap, ENC_UTF8);
187     }
188 
189     /**
190      * @Description: https协议 post zip
191      * @param url 请求地址
192      * @param paramsMap 参数map
193      * @param charset 字符集
194      * @return String 应答结果字符串
195      * @throws
196      * @author: syuf
197      * @date: 2018年1月9日 下午8:35:57
198      */
199     public static String postZip(String url, Map<String, String> paramsMap, String charset) {
200         return postZip(url, paramsMap, charset, DEFAULT_CONN_TIMEOUT, DEFAULT_READ_TIMEOUT);
201     }
202 
203     /**
204      * @Description: https协议 post zip
205      * @param url 请求地址
206      * @param paramsMap 参数map
207      * @param charset 字符集
208      * @param connOut 链接超时时间
209      * @param readOut 请求超时 时间
210      * @return String 应答结果字符串
211      * @throws
212      * @author: syuf
213      * @date: 2018年1月9日 下午8:36:37
214      */
215     public static String postZip(String url, Map<String, String> paramMap, String charset, int connOut, int readOut) {
216         return postZip(url, getParamStr(paramMap), charset, connOut, readOut);
217     }
218 
219     /**
220      * @Description: https协议 post zip
221      * @param url 请求地址
222      * @param paramData 参数数据
223      * @param charset 字符集
224      * @param connOut 链接超时时间
225      * @param readOut 请求超时 时间
226      * @return String 应答结果字符串
227      * @throws
228      * @author: syuf
229      * @date: 2018年1月9日 下午8:36:37
230      */
231     public static String postZip(String url, String paramData, String charset, int connOut, int readOut) {
232         BufferedReader in = null;
233         DataOutputStream out = null;
234         HttpsURLConnection uc = null;
235         StringBuffer sb = new StringBuffer();
236         try {
237             SSLContext sc = SSLContext.getInstance("SSL");
238             sc.init(null, new TrustManager[] { new MyTrustManager() }, new java.security.SecureRandom());
239             uc = (HttpsURLConnection) new URL(url).openConnection();
240             uc.setSSLSocketFactory(sc.getSocketFactory());
241             uc.setHostnameVerifier(new TrustAnyHostnameVerifier());
242             uc.setRequestMethod("POST");
243             uc.setDoOutput(true);
244             uc.setDoInput(true);
245             uc.setUseCaches(false);
246             uc.setConnectTimeout(connOut);
247             uc.setReadTimeout(readOut);
248             uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
249             uc.connect();
250             out = new DataOutputStream(uc.getOutputStream());
251             out.write(paramData.getBytes(charset));
252             out.flush();
253             out.close();
254             in = new BufferedReader(new InputStreamReader(new GZIPInputStream(uc.getInputStream()), charset));
255             String readLine = null;
256             while ((readLine = in.readLine()) != null) {
257                 sb.append(readLine).append("
");
258             }
259         } catch (Exception e) {
260             LOG.error("[HttpsClient POST GZIP]请求异常", e);
261         } finally {
262             close(in, uc, null, out);
263         }
264         return sb.toString();
265     }
266 
267     /**
268      * @Description: HTTPS协议POST请求方法
269      * @param url 请求地址
270      * @param paramsMap 请求参数 map
271      * @return String 应答结果字符串
272      * @throws
273      * @author: syuf
274      * @date: 2018年1月9日 下午12:30:39
275      */
276     public static String post(String url, Map<String, String> paramMap) {
277         return post(url, paramMap, ENC_UTF8);
278     }
279 
280     /**
281      * @Description: HTTPS协议POST请求方法
282      * @param url 请求地址
283      * @param paramsMap 请求参数 map
284      * @param charset 字符集
285      * @return String 应答结果字符串
286      * @throws
287      * @author: syuf
288      * @date: 2017年11月20日 下午5:02:08
289      */
290     public static String post(String url, Map<String, String> paramsMap, String charset) {
291         return post(url, paramsMap, charset, DEFAULT_CONN_TIMEOUT, DEFAULT_READ_TIMEOUT);
292     }
293 
294     /**
295      * @Description: HTTPS协议POST请求方法
296      * @param url 请求地址
297      * @param paramsMap 参数map
298      * @param charset 字符集
299      * @param connOut 链接超时时间
300      * @param readOut 响应超时时间
301      * @return String 应答结果字符串
302      * @throws
303      * @author: syuf
304      * @date: 2018年1月9日 下午12:27:13
305      */
306     public static String post(String url, Map<String, String> paramMap, String charset, int connOut, int readOut) {
307         return post(url, getParamStr(paramMap), charset, connOut, readOut);
308     }
309 
310     /**
311      * @Description: HTTPS协议POST请求方法
312      * @param url 请求地址
313      * @param param 参数字符串
314      * @param charset 字符集
315      * @param connOut  链接超时时间
316      * @param readOut 响应超时时间
317      * @return String 应答结果字符串
318      * @throws
319      * @author: syuf
320      * @date: 2018年1月9日 下午12:27:13
321      */
322     public static String post(String url, String param, String charset, int connOut, int readOut) {
323         String result = null;
324         BufferedReader in = null;
325         DataOutputStream out = null;
326         HttpsURLConnection uc = null;
327         StringBuffer sb = new StringBuffer();
328         try {
329             SSLContext sc = SSLContext.getInstance("SSL");
330             sc.init(null, new TrustManager[] { new MyTrustManager() }, new java.security.SecureRandom());
331             uc = (HttpsURLConnection) new URL(url).openConnection();
332             uc.setSSLSocketFactory(sc.getSocketFactory());
333             uc.setHostnameVerifier(new TrustAnyHostnameVerifier());
334             uc.setRequestMethod("POST");
335             uc.setDoOutput(true);
336             uc.setDoInput(true);
337             uc.setUseCaches(false);
338             uc.setConnectTimeout(connOut);
339             uc.setReadTimeout(readOut);
340             uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
341             uc.connect();
342             out = new DataOutputStream(uc.getOutputStream());
343             out.write(param.getBytes(charset));
344             out.flush();
345             out.close();
346             in = new BufferedReader(new InputStreamReader(uc.getInputStream(), charset));
347             String readLine = null;
348             while ((readLine = in.readLine()) != null) {
349                 sb.append(readLine).append("
");
350             }
351             result = URLDecoder.decode(sb.toString(), charset);
352         } catch (Exception e) {
353             LOG.error("[HttpsClient POST]请求异常", e);
354         } finally {
355             close(in, uc, null, out);
356         }
357         return result;
358     }
359 
360     /**
361      * @Description: postFile
362      * @param url 请求地址
363      * @param data 请求参数
364      * @return byte[] 二进制文件
365      * @throws
366      * @author: syuf
367      * @date: 2018年1月16日 上午10:44:32
368      */
369     public static byte[] postFile(String url, String data) {
370         return postFile(url, data, ENC_GBK);
371     }
372 
373     /**
374      * @Description: postFile
375      * @param url 请求地址
376      * @param data 请求参数
377      * @param charset 字符集
378      * @return byte[]二进制文件
379      * @throws
380      * @author: syuf
381      * @date: 2018年1月16日 上午10:23:29
382      */
383     private static byte[] postFile(String url, String data, String charset) {
384         return postFile(url, data, charset, DEFAULT_CONN_TIMEOUT, DEFAULT_READ_TIMEOUT);
385     }
386 
387     /**
388      * @Description: postFile
389      * @param url 请求地址
390      * @param data 请求参数
391      * @param charset 字符集
392      * @param connOut 连接超时时间
393      * @param readOut 读取超时时间
394      * @return byte []
395      * @throws
396      * @author: syuf
397      * @date: 2018年1月16日 上午10:24:19
398      */
399     private static byte[] postFile(String url, String data, String charset, int connOut, int readOut) {
400 
401         byte[] btFile = null;
402         BufferedReader in = null;
403         DataOutputStream out = null;
404         HttpsURLConnection uc = null;
405         ByteArrayOutputStream outStream = null;
406         try {
407             SSLContext sc = SSLContext.getInstance("SSL");
408             sc.init(null, new TrustManager[] { new MyTrustManager() }, new java.security.SecureRandom());
409             uc = (HttpsURLConnection) new URL(url).openConnection();
410             uc.setSSLSocketFactory(sc.getSocketFactory());
411             uc.setHostnameVerifier(new TrustAnyHostnameVerifier());
412             uc.setRequestMethod("POST");
413             uc.setDoOutput(true);
414             uc.setDoInput(true);
415             uc.setUseCaches(false);
416             uc.setConnectTimeout(connOut);
417             uc.setReadTimeout(readOut);
418             uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
419             uc.connect();
420             out = new DataOutputStream(uc.getOutputStream());
421             out.write(data.getBytes(charset));
422             out.flush();
423             out.close();
424             int respCode = uc.getResponseCode();
425             if (respCode != 200) {
426                 in = new BufferedReader(new InputStreamReader(uc.getInputStream(), charset));
427                 StringBuilder sb = new StringBuilder();
428                 char[] buff = new char[2048];
429                 int cnt = 0;
430                 while ((cnt = in.read(buff)) != -1) {
431                     sb.append(buff, 0, cnt);
432                 }
433                 in.close();
434                 LOG.warn("[HttpsClient POST FILE]{}" , sb.toString());
435                 return null;
436             }
437             InputStream inStream = uc.getInputStream(); // 获取文件流二进制数据
438             outStream = new ByteArrayOutputStream();
439             byte[] buffer = new byte[1024];
440             int len = 0;
441             while ((len = inStream.read(buffer)) != -1) {
442                 outStream.write(buffer, 0, len);
443             }
444             inStream.close();
445             btFile = outStream.toByteArray();
446         } catch (Exception e) {
447             LOG.error("[HttpsClient POST FILE]请求异常", e);
448         } finally {
449             close(in, uc, null, outStream);
450         }
451         return btFile;
452     }
453 
454     /**
455      * @Description: HTTPS协议POST File请求方法
456      * @param url 请求地址
457      * @param paramsMap 参数map
458      * @return byte[] 二进制文件
459      * @throws
460      * @author: syuf
461      * @date: 2018年1月9日 下午8:14:11
462      */
463     public static byte[] postFile(String url, Map<String, String> paramsMap) {
464         return postFile(url, paramsMap, ENC_UTF8);
465     }
466 
467     /**
468      * @Description: HTTPS协议POST File请求方法
469      * @param url 请求地址
470      * @param paramsMap 参数map
471      * @param charset 字符集
472      * @return byte[] 二进制文件
473      * @throws
474      * @author: syuf
475      * @date: 2017年11月20日 下午5:06:03
476      */
477     public static byte[] postFile(String url, Map<String, String> paramsMap, String charset) {
478         return postFile(url, getParamStr(paramsMap), charset, DEFAULT_CONN_TIMEOUT, DEFAULT_READ_TIMEOUT);
479     }
480 
481     /**
482      * @Description: HTTP协议POST请求添加参数的封装方法
483      * @param paramsMap 参数map   
484      * @return String 应答结果
485      * @throws
486      * @author: syuf
487      * @date: 2017年11月20日 下午3:46:11
488      */
489     private static String getParamStr(Map<String, String> paramsMap) {
490         StringBuffer param = new StringBuffer();
491         if (paramsMap == null) {
492             return param.toString();
493         }
494         for (Iterator<Map.Entry<String, String>> it = paramsMap.entrySet().iterator(); it.hasNext();) {
495             Map.Entry<String, String> e = it.next();
496             param.append("&").append(e.getKey()).append("=").append(e.getValue());
497         }
498         return param.toString().substring(1);
499     }
500 
501     /**
502      * @Description: 关闭IO
503      * @param in
504      * @param uc
505      * @param inStream
506      * @param outStream
507      * @return void
508      * @throws
509      * @author: syuf
510      * @date: 2017年11月20日 下午5:15:35
511      */
512     private static void close(BufferedReader in, HttpsURLConnection uc, InputStream inStream, OutputStream outStream) {
513         try {
514             if (in != null) {
515                 in.close();
516             }
517             if (uc != null) {
518                 uc.disconnect();
519             }
520             if (inStream != null) {
521                 inStream.close();
522             }
523             if (outStream != null) {
524                 outStream.close();
525             }
526         } catch (IOException e) {
527             LOG.error("[HttpsClient]关闭流异常", e);
528         }
529     }
530 
531 }
原文地址:https://www.cnblogs.com/syuf/p/8488197.html