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. 使用jetty-maven-plugin运行maven多项目

    1.准备工作 org.eclipse.jetty   jetty-maven-plugin    9.2.11.v20150529 jdk  1.7 maven  3.1 2.采用maven管理多项目 ...

  2. 关于Git bash 在win10重装系统情况下闪退并生成mintty.exe.stackdump文件的问题

    问题内容:在重装win10系统情况下,有可能会出现安装Git后右击Git bash会出现闪退并生成mintty.exe.stackdump文件 个人解决方案:查看网络上各位网友的意见和解决方法后,自己 ...

  3. json--pyton中obj与json的互转,js中obj与json的互转

    json 解释:json是一种跨平台的通用的数据格式 python中对象(obj)与json之间的相互转换 1.对象(obj)转json格式的字符串 json.dumps(res) res = () ...

  4. C#多线程编程系列(三)- 线程同步

    目录 1.1 简介 1.2 执行基本原子操作 1.3 使用Mutex类 1.4 使用SemaphoreSlim类 1.5 使用AutoResetEvent类 1.6 使用ManualResetEven ...

  5. 红帽子系统链接加vm15秘钥一份

    vm15秘钥:YZ718-4REEQ-08DHQ-JNYQC-ZQRD0 红帽子系统下载链接:http://www.ddooo.com/softdown/60964.htm

  6. Python 获取秒级时间戳与毫秒级时间戳

    原文:Python获取秒级时间戳与毫秒级时间戳 1.获取秒级时间戳与毫秒级时间戳 import time import datetime t = time.time() print (t) #原始时间 ...

  7. git fetch and git pull &冲突

    1.git fetch和git pull之间的区别 git fetch只会将本地库所关联的远程库的commit id更新至最新,fetch不会改变代码,如果想使代码更新,需要使用git merge o ...

  8. Storm的并行度

    在Storm集群中,运行Topolopy的实体有三个:工作进程,executor(线程),task(任务),下图可以形象的说明他们之间的关系. 工作进程 Storm集群中的一台机器会为一个或则多个To ...

  9. react native 学习之 native modules

    翻译自https://facebook.github.io/react-native/docs/native-modules-ios.html Native Modules 很多情况下,app需要使用 ...

  10. C#里面获取web和非web项目路径

    非Web程序获取路径几种方法如下: 1.AppDomain.CurrentDomain.BaseDirectory  2.Environment.CurrentDirectory 3.HttpRunt ...