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;
    }
目录
相关文章
|
6月前
restTemplate 发送http post请求带有文件流、参数
restTemplate 发送http post请求带有文件流、参数
158 1
|
API 图形学
U3D客户端框架之实现基于UnityWebRequest的Http服务 实现HttpCallBackArgs参数类、HttpRoutine访问器、HttpManager管理器
Unity3D 在2018版本中弃用了WWW请求,使用UnityWebRequest 进行网络请求,这个方法是为了满足今天的 HTTP 通信的需求,而且诞生的新类,相对于WWW这个方法,会更灵活一些,但是用起来却很不方便。
U3D客户端框架之实现基于UnityWebRequest的Http服务 实现HttpCallBackArgs参数类、HttpRoutine访问器、HttpManager管理器
|
数据采集 缓存 JSON
常见的http请求参数和响应参数,前后端交互参数说明
常见的http请求参数和响应参数,前后端交互参数说明
1579 1
|
应用服务中间件
解决Tomcat8及Tomcat7下http的post、get请求中参数中文乱码问题
解决Tomcat8及Tomcat7下http的post、get请求中参数中文乱码问题
283 0
|
JSON 缓存 网络协议
curl的HTTP参数速查表
curl是一个开源的命令行工具,它基于网络协议,对指定URL进行网络传输,得到数据后不任何具体处理(如:html的渲染等),直接显示在"标准输出"(stdout)上。 curl的参数也有很多,以下主要介绍HTTP和HTTPS相关的参数,建议收藏保存。
776 0
|
Web App开发 应用服务中间件 nginx
|
Web App开发 安全 测试技术
Web Hacking 101 中文版 六、HTTP 参数污染
六、HTTP 参数污染 作者:Peter Yaworski 译者:飞龙 协议:CC BY-NC-SA 4.0 描述 HTTP 参数污染,或者 HPP,在网站接受用户输入,将其用于生成发往其它系统的 HTTP 请求,并且不校验用户输出的时候发生。
1272 0
|
数据安全/隐私保护 Shell 数据库
ftp和http转参数的使用(转)
浏览器因特网资源:URL是浏览器寻找信息时所需的资源位置,通过URL,应用程序才能找到并使用共享因特网上大量的数据资源。   大部分URL都遵循一种标准的格式: ①HTTP协议(http://或者https://) ②服务器的因特网地址(www.
1067 0