HttpParams 的层级结构作用

14 篇文章 0 订阅

HttpClient 是基于java的Http Client端实现,其支持HTTP 1.0和HTTP 1.1, HttpClient自身对Http协议做了很多兼容,以便能和一些常用的Http 代理和Http server通信(这些代理和server没有严格按照协议标准来实现)。

HttpClient在本质上,是使用java的socket来和服务器通信,只不过通信的协议是采用HTTP协议而已。所以,为了成功通信,需要设置很多参数,主要分为两种:HTTP协议相关参数,(双方使用的协议版本号,是HTTP1.1还是HTTP1.0),还有一些是网络通信参数,比如连接的超时时间,是否使用tcpnodelay等。

HttpClient中,接口HttpParams定义了这些参数的通用接口,查看HttpParams,我们可以发现HttpParams支持层级结构,及一个HttpParams可以是另外一个HttpParams的parent,且当查找一个特定参数时,将从当前HttpParams中进行查找,如果当前层级中没有,则从其parent中进行查找。HttpParams的层级结构,是HttpClient设计上的一个特点。这样的设计,使得能够灵活的对httpclient进行参数设置。

在HttpClient中,具体实现了如下几种HttpParam,其类图结构如下:

点击链接

HttpClient在设计上比较有特色的就是将这些参数实现为有层级的,查找一个具体的参数时,先从最低的级别的param开始查,如果没有,则向其父级参数查询,当查到时,总是返回最低级别的参数。

那么HttpClient为何要如此设计这种参数体系结构呢?这样的设计有什么好处呢?

在使用HttpClient时,程序要要操作的主要是如下几个类:HttpClient,HttpConnectionManager,HttpConnection,HostConfiguration,HttpMethod。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使用)。

实例代码:

MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
HttpClient client = new HttpClient(connectionManager);

// 在某个线程中。
GetMethod getMethod = new GetMethod(“http://www.blogbus.com/”);
try {
client.executeMethod(getMethod);
// print response to stdout
System.out.println(get.getResponseBodyAsStream());
} finally {
// be sure the connection is released back to the connection
// manager
getMethod.releaseConnection();
}
HttpClient,HttpConnectionManager,HttpConnection,HostConfiguration,HttpMethod这些类,都可以接收对应的HttpParam参数,来对使用的http协议控制,但是不同的对象,其参数的范围大小不同,具有不同的层级。比如HttpConnectionManager参数的层级要比HttpConnection的层级要高。这里面有两个含义:1.当一个ConnectionManager和其管理的一个HttpConnection都设置了同样的一个参数时,那么取该参数值时,会取出HttpConnection的参数值,2.当ConnectionManager设置了一个参数,但是其管理的HttpConnection没有设置该参数时,则获取该参数值时,会取出ConnectionManager的参数值(这2点都可以从httpclient的参数体系结构上推出)。
点击链接
 
HttpClient中层级关系如下,HttpClient的参数层级要高于HttpHost和ConnectionManager的参数,HttpHost的参数层级要高于HttpMethod的参数,ConnectionManager的参数层级要高于HttpConnection的参数。这些类对应的参数类如下:
HttpClient<—->HttpClientParams|
|—- HttpConnectionManager<—–>HttpConnectionManagerParams
|                   |
|                   |—-HttpConnection<—>HttpConnectionParams
|—- HttpHost<—>HttpHostConfiguration<—>HttpHostParams|
|—-HttpMethod<—>HttpMethodParams
具体实例代码如下:
HttpClient httpclient = new HttpClient();
httpclient.getParams().setParameter(HttpClientParams.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
httpclient.getParams().setParameter(HttpClientParams.SO_TIMEOUT, new Integer(1000));
httpclient.getParams().setParameter(HttpClientParams.HTTP_CONTENT_CHARSET, “UTF-8″);
HostConfiguration hostconfig = new HostConfiguration();
hostconfig.setHost(“ www.yahoo.com “);

GetMethod httpget = new GetMethod(“/”);
httpget.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, new Integer(5000));

PostMethod httppost = new PostMethod(“/”);
try {
// Internally the parameter collections will be linked together
// by performing the following operations:
// hostconfig.getParams().setDefaults(httpclient.getParams());
// httpget.getParams().setDefaults(hostconfig.getParams());
httpclient.executeMethod(hostconfig, httpget);
httpclient.executeMethod(hostconfig,httppost);
System.out.println(“the http get:” + httpget.getParams().getParameter(HttpMethodParams.PROTOCOL_VERSION));
System.out.println(“the http get:” + httpget.getParams().getParameter(HttpMethodParams.SO_TIMEOUT));
System.out.println(“the http get:” + httpget.getParams().getParameter(HttpMethodParams.HTTP_CONTENT_CHARSET));

System.out.println(“the http post:” + httppost.getParams().getParameter(HttpMethodParams.SO_TIMEOUT));
}catch(HttpException e){

e.printStackTrace();
}catch(IOException ex){

ex.printStackTrace();
} finally {
httpget.releaseConnection();
}

则程序输出为:
the http get:HTTP/1.1
the http get:5000
the http get:UTF-8
the http post:1000
读到这里,我们大概能猜出来httpclient的参数体系为何要这样设计了,其实这样设计有2个理由:
1,参数有层级,不同层级的参数可能设置的参数类别存在不同。比如在HttpClient的params里可以设置使用的Http协议,但是HttpConnection的params就不适合做这个设置,它的params比较适合存放和底层socket控制相关的参数。
2,由于不同层级的params的范围不同,其适用场景也不同。比如有两个HttpMethod,其代表了访问在同一台服务器上的两个应用,但是这2个应用的响应速度不一样,一个很快,10ms就可以返回,一个很慢,要100ms才可以返回。
同时,假设这两个Method都是用的同一个httpconnection(串行使用),那么在设置读超时时,我们应该在HttpMethod上进行设置,因为这个是和具体的应用程序的响应时间有关;而设置连接超时,则只需要在httpconnection上进行设置即可,因为2个应用都在同一台机器上,其网络链接耗时情况是一样的。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值