目前C/S还是B/S结构的应用程序, HTTP 应该是最为广泛使用的协议了。在 Java 平台上,Java 标准库提供了 一个HttpURLConnection 类来支持 HTTP 通讯。不过 HttpURLConnection 本身的 API 不够友好,所提供的功能也有限。httpClien是一个实现http协议很多操作功能的组件,并且它支持 HTTP 协议最新的版本和建议,现在Android已经成功的集成了HttpClient。另外,最新由Square 公司开源的 OkHttp 据说能提供更高效率的http连接,支持GZIP 压缩和 HTTP 响应缓存功能,在原理上应该是大同小异的。
再说httpclient ,那也是眼花缭乱。随便一搜,比如有些博文使用了 org.apache.commons.httpclient.HttpClient ,有些博文用org.apache.http.client.HttpClient 类。原来,httpclient本来是属于apache-commons 项目下的一个子项目,后来是由Apache HttpComponents项目开发了后面的版本以提供更好的性能和更大的灵活性。commons下的这个httpclient最高版本是目前的3.1,支持HTTP协议1.1,继承了java.net.urlConnection,已经足够提供目前测试的大部分rest服务接口,本文介绍一下用法。这里可以查看所有的API – http://hc.apache.org/httpclient-3.x/apidocs/overview-summary.html
在金融产品的测试过程中,我曾经碰到的服务接口有区分,比如与合作方交互一般是传xml较多,单应用的后台一般是http rest服务。这里提供一个传json的例子。
public void urlPostJson(String url,String desc,String json) {
log.info(“—————————–“+desc+” Request: ” + json);
HttpClient client = new HttpClient();
client.getHostConfiguration().setProxy(“127.0.0.1”, 5689);
client.getHttpConnectionManager().getParams().setConnectionTimeout(3000);// client.setConnectionTimeout(3000);
client.getParams().setSoTimeout(3000);// client.setTimeout(1000);
client.getParams().setConnectionManagerTimeout(1000);
PostMethod method = new PostMethod(url);
try {
// method.setRequestHeader(“Content-Type”, ” application/json; charset=UTF-8″);
method.setRequestBody(new ByteArrayInputStream(json.getBytes(“UTF-8”)));
// method.setRequestBody(json);
int status = client.executeMethod(method);
String res=method.getResponseBodyAsString();
log.info(” status:”+status+” Resonse: “+res);
} catch (IOException e) {
log.error(“HttpClient.executeMethod(postMethod) IOException!”,e);
}finally{
if (method != null) {
method.releaseConnection();
}
}
}
如上,利用httpclient去访问接口的步骤一般是:
1. 创建HttpClient对象。2. 构造Http 请求对象。3. 执行HttpClient对象的execute方法,将Http请求对象作为该方法的参数。4. 读取execute方法返回的HttpResponse结果并解析。5、释放连接。整个过程是不是与我们平时在浏览器上访问类似呢。唯一区别是不能执行HTTP页面中签入嵌入的JS代码,自然也不会对页面内容进行任何解析、处理,这些都是需要开发人员来完成的。在以上代码中,httpclient的初始化没有看到任何参数设置,其实是在它的构造函数里调用了接口,并设置了默认值,如下包含协议版本、客户端引擎、cookie策略等,如果要自己设置,可以通过它的成员变量httpClientParams对象进行设置。
1、关于重定向。
http多种状态已经在HttpStatus这个类中定义好,其中重定向 根据RFC2616中对自动转向的定义,主要有两种:301和302。301表示永久的移走(Moved Permanently),当返回的是301,则表示请求的资源已经被移到一个固定的新地方,任何向该地址发起请求都会被转到新的地址上。302表示暂时的转向,比如在服务器端的servlet程序调用了sendRedirect方法,则在客户端就会得到一个302的代码,这时服务器返回的头信息中location的值就是sendRedirect转向的目标地址。如果是get方式请求,httpclient是自动帮你重定向并拿到响应信息,也可以通过设置method.setFollowRedirects(false)不自动转。post的请求是不能自动跳转的,需要从头部信息中拿到Location(可能是相对路径)因此需要对location返回的值做一些处理才可以发起向新地址的请求。
2、字符编码
客户端发送的数据多样,最终所有数据都是通过最底层的物理层面的电信号来传递,首部字段content-type 说明了实体主体内对象的媒体类型,即服务器通过contentType来知道这个是什么样子的数据。客户端在拿到服务器返回的数据后,根据头部设置的可接收媒体类型进行内容协商,返回最适合的资源。对于有中文的请求,为避免出现乱码,最好设置content-type。在上部分的代码截图,大家可以看到,如果我们自己不设置contentType 那么默认会采用ISO的方式进行传输,那么如果与你实际的编码方式不一致的话,服务器就会拿到一个乱码,从而无法正常的响应。可以通过上面代码进行设置,也可以通过method.setRequestHeader(“Content-Type”, ” application/json; charset=UTF-8″)来进行设置
3、cookie
httpclient默认的cookie策略是RFC_2109其中可以通过去更改。请求过程中可以通过sendHead 把cookie放入头部,并传到后端进行访问。
总结:
基本上使用httpclient过程中,主要操作的类有:httpclient,getMethod,postMethod,httpClientParams,httpConnectionManager这几个。详见以下的类图。
HttpClient代表了一个http的客户端,HttpConnectionManager是用来管理HttpConnection 的,HttpConnection代表了一个http连接,所以HttpConnectionManager其实质上也就是一个http连接池,管理这些 http连接(和数据库连接池一个道理)。HttpMethod代表了一个Http方法,一个HttpClient可以运行多个HttpMethod(实 质上,httpclient执行一个HttpMethod时,会从connectionmanager那里获取一个httpconnection,在此 connection上执行该method,执行完该method后,让method 释放该httpconnection,从而将该httpconnection返回给connectionmanager,以便供后续的method使 用)所以在httpclient连接后资源释放问题很重要,就跟我们用database connection要释放资源一样。
4、小tips
1、fidder作为一款强大好用的web调试利器,针对commons下的httpclient可以如下设置代理,能帮你记录下请求和响应的所有信息。 接口测试中遇到异常方便查看,减少自己debug的情况。
5、扩展
httpclient功能之强大,不是一篇文章能够说完。其他的,例如文件上传、DNS配置、多线程下的httpclient使用。过程中需要你对http协议、cookie-session机制有一定的认识基础。本篇文件旨在用做一些简单接口的测试,目前commons这个版本已经不做更新了,如果有更复杂的接口,还是推荐使用org.apache.http.impl.client下的httpclient。
Java语言使用HttpClient模拟浏览器登录 http://www.linuxidc.com/Linux/2016-05/131214.htm
HttpClient4.3 关于https 中SSL证书请求问题 http://www.linuxidc.com/Linux/2016-04/130090.htm
HttpClient4 用法 由HttpClient3 升级到 HttpClient4 必看 http://www.linuxidc.com/Linux/2015-06/119100.htm
HttpClient 教程 http://www.linuxidc.com/Linux/2015-06/119099.htm
使用HttpClient实现文件的上传下载 http://www.linuxidc.com/Linux/2014-07/104303.htm
Android 实现 HttpClient 请求Https http://www.linuxidc.com/Linux/2014-05/102306.htm
Android使用HttpClient下载图片 http://www.linuxidc.com/Linux/2014-05/101855.htm
HttpClient使用详解 http://www.linuxidc.com/Linux/2014-08/104945.htm
本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-11/137590.htm