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. what is HTTP OPTIONS verb

    The options verb is sent by browser to see if server accept cross origin request or not, this proces ...

  2. Sharepoint 安装部署Project Server

    #在SharePoint Central Administration-> Manage service applications中,点击New button,选择Project Service ...

  3. [Openwrt 项目开发笔记]:Openwrt平台搭建(一)补遗

    [Openwrt项目开发笔记]系列文章传送门:http://www.cnblogs.com/double-win/p/3888399.html 正文: 昨晚上熬夜写了[Openwrt项目开发笔记]:O ...

  4. [ACM_动态规划] UVA 12511 Virus [最长公共递增子序列 LCIS 动态规划]

      Virus  We have a log file, which is a sequence of recorded events. Naturally, the timestamps are s ...

  5. SQL SERVER 2014--学习笔记1

    --======================================================= 在SQL SERVER 2014中,最吸引眼球的就是内存表和本地编译存储过程,在MS ...

  6. dorado-menu

    1.menu控件是一个下拉菜单控件,可以设置数icon(图标),click事件,Dorado事件中都有self和arg两个参数,其中self是当前控件本身 2.menu控件可以和toolBar结合使用 ...

  7. pgAdmin4 汉化

  8. Python初学手记----在window系统中安装环境

    官网地址: https://www.python.org/ Win版下载地址:https://www.python.org/downloads/windows/ 安装注意:安装路径推荐修改. path ...

  9. C#多线程编程系列(二)- 线程基础

    目录 C#多线程编程系列(二)- 线程基础 1.1 简介 1.2 创建线程 1.3 暂停线程 1.4 线程等待 1.5 终止线程 1.6 检测线程状态 1.7 线程优先级 1.8 前台线程和后台线程 ...

  10. CentOS 6 - 升级内核

    有的时候,需要升级Linux内核,今天我就是在CentOS 6中升级内核,在没有升级内核之前,我的CentOS 6只有2.6.32这一个内核,也是默认启动的内核.下面就开始一步步操作升级内核了! 一, ...