HttpClient和HttpGet 参数的优先级

一般在使用HttpClient时,我们提前设置好参数,比如超时时间(一般socket超时和连接超时)

private DefaultHttpClient createHttpClient() { //代码1
        ThreadSafeClientConnManager connectMag = new ThreadSafeClientConnManager();
        ...
        client = new DefaultHttpClient(connectMag);
        client.getParams().setParameter(CoreProtocolPNames.USER_AGENT,
                "...");
        client.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT,
                2000);
        client.getParams().setIntParameter(
                CoreConnectionPNames.CONNECTION_TIMEOUT, 1000);
        return client;
    }

但是我们也可以通过HttpUriRequest来设置参数,比如HttpGet、HttpPost。

httpGet.getParams().setIntParameter(
                    CoreConnectionPNames.SO_TIMEOUT, 5000);
            httpGet.getParams().setIntParameter(
                    CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);
httpclient.execute(httpGet, new BasicResponseHandler());

 

 

这里的问题是:当我们既在HttlClent设置了超时时间,又在HttpGet设置了超时时间,那么到底以哪个设置为准?

仔细查看代码,发现httpclient.execute最终调用了以下代码,创建了RequestDirector director,在创建director中通过determineParams(request))函数设置了参数。

 

public final HttpResponse execute(HttpHost target, HttpRequest request,
                                      HttpContext context)
        throws IOException, ClientProtocolException {

        if (request == null) {
            throw new IllegalArgumentException
                ("Request must not be null.");
        }
        // a null target may be acceptable, this depends on the route planner
        // a null context is acceptable, default context created below

        HttpContext execContext = null;
        RequestDirector director = null;

        // Initialize the request execution context making copies of
        // all shared objects that are potentially threading unsafe.
        synchronized (this) {

            HttpContext defaultContext = createHttpContext();
            if (context == null) {
                execContext = defaultContext;
            } else {
                execContext = new DefaultedHttpContext(context, defaultContext);
            }
            // Create a director for this request
            director = createClientRequestDirector(
                    getRequestExecutor(),
                    getConnectionManager(),
                    getConnectionReuseStrategy(),
                    getConnectionKeepAliveStrategy(),
                    getRoutePlanner(),
                    getProtocolProcessor(),
                    getHttpRequestRetryHandler(),
                    getRedirectStrategy(),
                    getTargetAuthenticationHandler(),
                    getProxyAuthenticationHandler(),
                    getUserTokenHandler(),
                    determineParams(request)); //设置了参数
        }

        try {
            return director.execute(target, request, execContext);
        } catch(HttpException httpException) {
            throw new ClientProtocolException(httpException);
        }
    }

 

 

那determineParams(request))函数干了什么呢?其实是创建了个HttpParams,也就是ClientParamsStack(ClientParamsStack extends AbstractHttpParams,而AbstractHttpParams implements HttpParams)。

ClientParamsStack拿来干什么用的呢?Represents a stack of parameter collections. When retrieving a parameter, the stack is searched in a fixed order and the first match returned. Setting parameters via the stack is not supported. To minimize overhead, the stack has a fixed size and does not maintain an internal array. The supported stack entries, sorted by increasing priority (摘自:http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/client/ClientParamsStack.html)

 

上面大意是:ClientParamsStack是个参数栈,这个参数栈里有四个参数,参数优先级是越来越高的,i.e. applicationParams < clientParams < requestParams < overrideParams,从这里可以看出requestParams优先级比clientParams高(在本例中,requestParams是从HttpGet设置的,而clientParams是HttpClient设置的),也就是说当HttpGet和HttpClient同时设置了超时时,以HttpGet设置的为准!

 

protected HttpParams determineParams(HttpRequest req) {
        return new ClientParamsStack
            (null, getParams(), req.getParams(), null);
    }

 

 

 

public ClientParamsStack(HttpParams aparams, HttpParams cparams,
                             HttpParams rparams, HttpParams oparams) {
        applicationParams = aparams;
        clientParams      = cparams;
        requestParams     = rparams;
        overrideParams    = oparams;
    }

 

 

既然各个参数有优先级,那么优先级是如何实现的呢?其实原理很简单,也就是按overrideParams、requestParams、clientParams、applicationParams的顺序依次判断,如果不为空就返回。(注:getParameter()函数经常被底层实现用到)

 

public Object getParameter(String name) {
        if (name == null) {
            throw new IllegalArgumentException
                ("Parameter name must not be null.");
        }

        Object result = null;

        if (overrideParams != null) {
            result = overrideParams.getParameter(name);
        }
        if ((result == null) && (requestParams != null)) {
            result = requestParams.getParameter(name);
        }
        if ((result == null) && (clientParams != null)) {
            result = clientParams.getParameter(name);
        }
        if ((result == null) && (applicationParams != null)) {
            result = applicationParams.getParameter(name);
        }
        return result;
    }
时间: 2024-09-13 05:17:32

HttpClient和HttpGet 参数的优先级的相关文章

java网络编程-java中HttpGet和HttpClient和HttpResponse之间的联系是如何的

问题描述 java中HttpGet和HttpClient和HttpResponse之间的联系是如何的 java中HttpGet和HttpClient和HttpResponse之间的联系是如何的 每一个对象分别承载着什么信息 解决方案 public class HTTPGetSample { public static void main(String[] args) throws ClientProtocolException, IOException { String url = "http:

Cookies,SSL,httpclient的多线程处理,HTTP方法

client|cookie|cookies|多线程 - 作者 sunggsun @ 20:26 8.Cookies HttpClient能自动管理cookie,包括允许服务器设置cookie并在需要的时候自动将cookie返回服务器,它也支持手工设置cookie后发送到服务器端.不幸的是,对如何处理cookie,有几个规范互相冲突:Netscape Cookie 草案, RFC2109, RFC2965,而且还有很大数量的软件商的cookie实现不遵循任何规范. 为了处理这种状况,HttpCli

Android通过HttpURLConnection与HttpClient联网代理网关设置

Android联网主要使用HttpURLConneciton和HttpClient进行联网,在手机联网 的时候,我们优先选择wifi网络,其次在选择移动网络,这里所述移动网络主要 指cmwap. 大家都知道cmwap连接需要设置代理地址和端口,那么,android程序中如何设 置代理呢?这是个问题. HttpURLConnection设置代理 //当我们使用的是中国移动的手机网络时,下面方法可以直接获取得到 10.0.0.172,80端口 String host=android.net.Prox

论述Android通过HttpURLConnection与HttpClient联网代理网关设置

 Android联网主要使用HttpURLConneciton和HttpClient进行联网,在手机联网的时候,我们优先选择wifi网络,其次在选择移动网络,这里所述移动网络主要指cmwap. 大家都知道cmwap连接需要设置代理地址和端口,那么,android程序中如何设置代理呢?这是个问题. HttpURLConnection设置代理 1 //当我们使用的是中国移动的手机网络时,下面方法可以直接获取得到10.0.0.172,80端口 2 String host=android.net.Pro

android之HttpPost&amp;amp;HttpGet使用方法介绍_Android

直接讲用法,先知道怎么用,再知道怎么回事 1.HttpPost 复制代码 代码如下: try{ //创建连接 HttpClient httpClient = new DefaultHttpClient(); HttpPost post = new HttpPost(url); //设置参数,仿html表单提交 List<NameValuePair> paramList = new ArrayList<NameValuePair>(); BasicNameValuePair para

Java4Android之httpclient学习与应用

在Java开发中,不可避免的需要和http打交道.而无论我司的迅雷动漫还是我主导的"搜芽"android客户端开发,都需要使用到http和服务器打交道..虽然Java也提供了http的接口,但据我了解,更多的公司都是使用Apache的httpclient来进行开发,不仅因为它灵活强大,而且便捷. 今天,我们学习httpclient的基础知识. 关于Http的基础,在此就不再复习了.建议大家去看一本权威制作<HTTP权威指南>,加个略贵,109元人民币,不过,我买了,因为经典

服务器-使用HttpClient通过Post发送数据,如何显示到Web界面上

问题描述 使用HttpClient通过Post发送数据,如何显示到Web界面上 以前没有接触过android和服务器的交互,在上网找了一个Demo 试着做了一下,在android上写的数据可以在后台打印输出,但是如何在Web服务器上显示出来,求指教.代码如下: package com.example.m04_http02; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Array

HttpClient连接池原理及一次连接时序图

1.       httpClient介绍 HttpClient是一个实现了http协议的开源Java客户端工具库,可以通过程序发送http请求.   1.1.  HttpClient发送请求和接收响应 1.1.1.      代码示例 以Get请求为例,以下代码获得google主页内容并将返回结果打印出来. public final static void main(String[] args) throws Exception {           HttpClient httpclien

Using HttpClient properly to avoid CLOSE_WAIT TCP connections

         Apache的HttpComponent(这里是基于 version 4.1)组件,用的人不在少数.但是能用好的人,却微乎其微,为什么?很简单,TCP/IP协议里面的细节太多了(细节是魔鬼),像并发请求控制&资源释放,Nagle算法参数优化,Connection eviction,跟ulimit配对的total connection,重定向策略定制化,两类超时时间的合理设置,流读写等等.          在最近的项目中,更是破天荒的遇到了close_wait问题,所以利用业余