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 }