http://www.cnblogs.com/LBSer/p/3295584.html

一般在使用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;
}

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

  1. 使用httpClient调用接口,参数用map封装或者使用JSON参数,并转换返回结果

    这里接口用表存起来,标记请求方式,然后接受参数,消息或者请求参数都可以, 然后先是遍历需要调用的接口,封装参数,再分别调用get与post即可,没有微服务还是得自己写 //消息转发-获取参数中对应参数 ...

  2. httpclient提交json参数

    private void httpReqUrl(List<HongGuTan> list, String url) throws ClientProtocolException, IOEx ...

  3. provider和consumer配置参数的优先级

    <dubbo:service>和<dubbo:reference>存在一些相同的参数,例如:timeout,retries等,那么哪个配置的优先级高呢? consumer合并u ...

  4. Dubbo配置参数的优先级

    总结为: 1).Java运行时虚拟机参数 eg:-Ddubbo.protocol.port=20880 2).dubbo.xml || application.properties(SpringBoo ...

  5. HttpClient实现POST参数提交

    HttpClient client = new HttpClient(); //使用FormUrlEncodedContent做HttpContent var content = new FormUr ...

  6. new HttpClient().PostAsync封装参数

    var data = Encoding.UTF8.GetBytes("{ \"y\": 5, \"x\": 3}"); var conten ...

  7. Request.Params用法,后台接收httpget参数

    使用Request.Params["id"]来获取参数是一种比较有效的途径. request.params其实是一个集合,它依次包括request.querystring.requ ...

  8. Java HttpClient Post请求参数格式为XML

    1.最近忙着做一个接口,拿到文档的时候,what?我当时就震惊了,全都是XML数据传输. 我当时就懵了,哎没得办法,在暑假传输这方面笔者比较熟练json格式数据,简单易懂啊 那就学呗. 2.我在使用的 ...

  9. HTTPClient模块的HttpGet和HttpPost

    HttpClient常用HttpGet和HttpPost这两个类,分别对应Get方式和Post方式. 无论是使用HttpGet,还是使用HttpPost,都必须通过如下3步来访问HTTP资源. 1.创 ...

随机推荐

  1. Oracle SQL性能优化技巧大总结

    http://wenku.baidu.com/link?url=liS0_3fAyX2uXF5MAEQxMOj3YIY4UCcQM4gPfPzHfFcHBXuJTE8rANrwu6GXwdzbmvdV ...

  2. SSH登录警告(WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!)

    在配置本机与docker容器实现ssh无密码访问时出现以下报错 # federico @ linux in ~ [18:35:52] C:127$ sudo ssh-copy-id -i .ssh/i ...

  3. java 实例化泛型且赋值

    实例化泛型 Class <T> clazz = (Class <T>) ((ParameterizedType) new Entity().getClass().getGene ...

  4. ADO.NET操作PostgreSQL:数据库操作类(已封装)

    1.增.删.改通用方法 /// <summary> /// 增.删.改通用方法 /// </summary> /// <param name="commandT ...

  5. GitHub设置使用SSH Key,用TortoiseGit进行Clone仓库

    GitHub设置使用SSH Key的好处就是可以使用SSH连接,并且提交代码的时候可以不用输入密码,免密提交. 生成SSH Key 这里我们使用PuTTYgen来生成公钥(Public Key),私钥 ...

  6. 【cocos2d-x + Lua(1) 绑定Lua并使用tolua++】

    为什么要使用Lua进行游戏开发?转载请注明出处http://www.cnblogs.com/zisou/p/cocos2dx-lua1.html 上面一个问题我觉得在我们使用Lua之前需要深入思考的, ...

  7. c# 1-2+3-4.....求和

    找规律: 下界:1 上界:n class Program { static void Main(string[] args) { ; ; i <=; i++) { ==) { sum -= i; ...

  8. 守护进程与Supervisor

    博客链接:http://www.cnblogs.com/zhenghongxin/p/8676565.html 消息队列处理后台任务带来的问题 在系统稍微大些的时候,我们经常会用到消息队列(实现的方式 ...

  9. Mysql数据库二:表的增删改查

    ----建表CREATE TABLE emp( id int PRIMARY key auto_increment, name char(10) , birthday DATE , salary FL ...

  10. ElasticSearch的概念解析

    ElasticSearch是面向文档的,它不仅仅可以存储整个对象或则文档(document),还会索引(index)每个文档的内容使它可以被快速的检索.ElasticSearch和关系型数据库的对比如 ...