HttpClient 是什么:
HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
HttpClient 主要功能:
实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
支持自动转向
支持 HTTPS 协议
支持代理服务器等
HttpClient包下面都有那些内容:
HttpClient 的基本使用方法:
Get方法:
使用 HttpClient 需要以下 6 个步骤:
- 创建 HttpClient 的实例
- 创建某种连接方法的实例,在这里是 GetMethod。在 GetMethod 的构造函数中传入待连接的地址
- 调用第一步中创建好的实例的 execute 方法来执行第二步中创建好的 method 实例
- 读 response
- 释放连接。无论执行方法是否成功,都必须释放连接
- 对得到后的内容进行处理
Demo 示例:
1 | //构造HttpClient的实例 |
注意点:
- HttpClient的恢复策略是指在遇到异常时自动重试的机制,并且可以自定义(通过实现接口HttpMethodRetryHandler来实现)。通过httpClient的方法setParameter设置你实现的恢复策略,demo中使用的是系统提供的默认恢复策略,该策略在碰到IOException的时候将自动重试3次。
- 用GetMethod将会自动处理重定向,如果想要把自动处理重定向去掉的话,可以调用方法setFollowRedirects(false)。
- executeMethod返回值是一个整数,表示了执行该方法后服务器返回的状态码;
- 获取响应内容的方式有三种:getResponseBody(返回二进制byte流)、getResponseBodyAsString(返回String)、getResponseBodyAsStream(这个方法对返回大量数据处理效率很高);
- 乱码:在使用getResponseBodyAsString容易出现乱码,影响响应内容字符编码的地方有两个:第一,Response的header设置,这里的设置编码可能与html内容编码不符,通过method对象的getResponseCharSet()方法就可以得到http头中的编码信息;第二,Respone的body内容中设置了
<meta http-equiv=”Content-Type” content=”text/html; charset=GBK”/>或<?xml version=”1.0″ encoding=”GBK”?>
标签,这样也可能与header编码冲突造成乱码。 - 释放连接。无论执行方法是否成功,都必须释放连接。
1 | method.releaseConnection(); |
Post方法:
PostMethod基本与GetMethod类似;
不同点:
- POST和PUT,不支持自动重定向,因此需要自己对页面转向做处理。
Proxy代理服务的使用(host绑定):
在日常工作中很多url的访问都是需要绑定host地址的,使用httpClient如何进行绑定访问?
1 | HttpClient httpclient = new HttpClient(); |
支持Https:
HttpClient提供了对SSL的支持,允许HttpClient来打开Https连接。
有两种方法可以打开https连接,第一种就是得到服务器颁发的证书,然后导入到本地的keystore中;另外一种办法就是通过扩展HttpClient的类来实现自动接受证书。
方法1参考:处理HTTPS协议
方法2:
- 实现自己的socket factory,必须实现SecureProtocolSocketFactory接口。
- 自定义私有类 TrustAnyTrustManager implements X509TrustManager。
- 定义Protocol ,将socket factory注册到 Protocol中。
1 | Protocol myhttps = new Protocol("https", new MySecureProtocolSocketFactory(), 443); |
Cookie处理:
通过state获取cookie:httpclient.getState().getCookies();
1 | CookieSpec cookiespec = CookiePolicy.getDefaultSpec(); |
CookieSpec接口代表了cookie管理的规范。cookiespec.match获取匹配路径下的cookie数组。
通过state设置cookie:
1 | httpclient.getParams().setCookiePolicy(CookiePolicy.RFC_2109);//RFC_2109是支持较普遍的一个,还有其他cookie协议 |
cookie协议:RFC 2109(过时的严格策略)、RFC 2965(严格策略的标准符合)、best-match:最佳匹配meta(元)策略(推荐使用)。
携带cookie进行页面访问:
1 | postMethod.setRequestHeader("Cookie", cookieToString(cookies)); |
httpClient本身就可以保持cookie,可以通过同一个httpclient进行页面登录访问,但是对于有页面跳转的只能使用自带cookie进行模拟登录后访问。
通过HTTP上传文件:
httpclient使用了单独的一个HttpMethod子类来处理文件的上传,这个类就是MultipartPostMethod,该类已经封装了文件上传的细节,我们要做的仅仅是告诉它我们要上传文件的全路径即可。
1 | ArrayList<Part> partArray = new ArrayList<Part>(); |
通过HTTP模拟登录:
1 | public static String LoginDailyToGetPageWithHost(String nick, String psw, String scopeString, String url, List<NameValuePair> params, String hostIp, Integer hostIpPort) throws IOException { |
MySecureProtocolSocketFactory 的实现:
1 | public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory { |
HttpClient 使用中的坑:
为什么 返回状态吗 为 200,但是 responebody = null ?
原因:在执行完 executeMethod 方法后,立即使用 getMethod.getResponseBodyAsString() 得到的是null,
通过在 executeMethod 后面打印出 返回体后在获取 返回内容,这时就能获取到了,添加 if (getresult == HttpStatus.SC_OK) 判断条件后也能获取到,说明 返回值内容不是立即写入的,有延迟。
解决方案: 添加 是否成功的判断。在进行请求的发生时,经常会遇到构建url参数时没有添加协议头:http://,这样会抛状态异常。
new HttpGet(url) 时出现 java.net.URISyntaxException 错误?
原因:url 中涉及了特殊字符,如‘|’‘&’等。所以不能直接用String代替URI来访问。必须采用%0xXX方式来替代特殊字符。但这种办法不直观。所以只能先把String转成URL,再能过URL生成URI的方法来解决问题.
解决方案①:
1 | URL url = new URL(strUrl); |
有时候会越到 把http://头也给替换掉了,这样就会引发其它异常,所以还有一种比较保险的做法是使用queryString构建参数部分:
1 | String url = "http://**.**.com/user/deployPackInfoDetail.htm"; |