httpclient的api变化很快,本篇随笔记录自己使用4.3.6版本时所做的设置。版本虽然不是最新,但达到了目的就行。

maven依赖:

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.6</version>
</dependency> 请求设置的方法:
//4.3版本不设置超时的话,一旦服务器没有响应,等待时间N久(>24小时)
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(20000) //建立连接超时时间
   .setSocketTimeout(10000) //获取数据超时
.setConnectionRequestTimeout(10000) //从连接池中取出的时间
.setCookieSpec(CookieSpecs.BEST_MATCH) //cookie的识别方式,还有浏览器兼容、标准方式、不管理使用cookie等方式
  .build();

在使用时发现如果将cookieSpec设置为标准可能会提示识别不了XSRF-TOKEN等cookie,而使用最佳匹配没有问题。

设置支持https请求:

private SSLConnectionSocketFactory getSSLSF(){
SSLContextBuilder builder = new SSLContextBuilder();
// builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
try {
builder.loadTrustMaterial(null, new TrustStrategy(){
public boolean isTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
return true;
}
});
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
}
SSLConnectionSocketFactory sslsf = null;
try {
sslsf = new SSLConnectionSocketFactory(builder.build(),SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return sslsf;
}
//httpClient.setSSLSocketFactory(sslsf)或者通过连接管理器来设置setConnectionManager(使用下面的代码给连接池管理器设置使用http/https)
private PoolingHttpClientConnectionManager getConnectionManager(SSLConnectionSocketFactory sslsf){ Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", new PlainConnectionSocketFactory()) .register("https", sslsf) .build(); PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry); //org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool //出现大量上述异常不是连接池不够大,可能是maxPerRoute的值太小了,或者是没有释放资源,The fix is, the response entity need to be consumed. cm.setMaxTotal(2000);//max connection cm.setDefaultMaxPerRoute(200);//该值默认较小,表示对每个目标地址的连接数不超过200//(目前只有一个路由,因此可以让他等于最大值) //另外设置http client的重试次数,默认是3次;当前是禁用掉(如果项目用不到,这个默认即可) //httpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(0, false)); //cm.closeExpiredConnections(); return cm; }

设置httpclient可随时切换代理地址

client.setRoutePlanner (HttpRoutePlanner routePlanner)

public class DynamicProxyRoutePlanner implements HttpRoutePlanner {
private DefaultRoutePlanner planner = null; /**
* @param host 为null时不使用代理
*/
public DynamicProxyRoutePlanner(HttpHost host){
if(host==null){
planner=new DefaultRoutePlanner(DefaultSchemePortResolver.INSTANCE);
}else
planner = new DefaultProxyRoutePlanner(host);
} /**
* change proxy
* @param host apply null for not using proxy
*/
public void setProxy(HttpHost host){
if(host==null){
planner=new DefaultRoutePlanner(DefaultSchemePortResolver.INSTANCE);
}else
planner = new DefaultProxyRoutePlanner(host);
}
//Override 接口中的方法实现
public HttpRoute determineRoute(HttpHost target, HttpRequest request, HttpContext context) throws HttpException {
return planner.determineRoute(target, request, context);
}
}

切换代理时使用routePlanner.setProxy(httpHost);

控制CookieStore

你也许想对cookie进行持久存储,或做更多的控制,可以通过实现CookieStore接口或继承BasicCookieStore。

如获取cookie字符串:

public class MyCookieStore extends BasicCookieStore{
//用于在setHeader中整个替换,向服务器发送的cookie只包括键和值而不包括失效日期等。
@Override
public synchronized String toString() {
StringBuilder builder = new StringBuilder(); for (Cookie c :super.getCookies())
{
builder.append(c.getName()).append("=")
.append(c.getValue()).append("; ");
}
if(builder.length()==0) return null;
return builder.substring(0,builder.length()-2).toString();
}
}

转成JSON格式的字符串,用于保存和恢复:

//先写一个类用于转换,使用了FastJSON (你可以换成其他的工具)
public class CookieMapper {
public Cookie toCookie(JSONObject jsonObject) throws JSONException {
BasicClientCookie2 cookie = new BasicClientCookie2(jsonObject.getString("name"), jsonObject.getString("value"));
cookie.setComment(jsonObject.getString("comment"));
cookie.setCommentURL(jsonObject.getString("commentURL"));
cookie.setDomain(jsonObject.getString("domain"));
cookie.setPath(jsonObject.getString("path"));
cookie.setSecure(jsonObject.getBooleanValue("secure"));
cookie.setVersion(jsonObject.getIntValue("version"));
Long timeLong=jsonObject.getLong("expiryDate");
if(timeLong != null)//注意getLong返回的对象可能为空,而getLongValue可以返回0
cookie.setExpiryDate(new Date(timeLong));
if (jsonObject.containsKey("ports")) {
cookie.setPorts(JSONArrayToArray(jsonObject.getJSONArray("ports")));
}
return cookie;
} public JSONObject toJSONObject(Cookie cookie) throws JSONException {
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", cookie.getName());
jsonObject.put("value", cookie.getValue());
jsonObject.put("comment", cookie.getComment());
jsonObject.put("commentURL", cookie.getCommentURL());
jsonObject.put("domain", cookie.getDomain());
jsonObject.put("path", cookie.getPath());
jsonObject.put("secure", cookie.isSecure());
jsonObject.put("version", cookie.getVersion());
if (cookie.getExpiryDate() != null) {
jsonObject.put("expiryDate", cookie.getExpiryDate().getTime());
}
if (cookie.getPorts() != null) {
JSONArray jsonArray = arrayToJSONArray(cookie.getPorts());
jsonObject.put("ports", jsonArray);
}
return jsonObject;
} private JSONArray arrayToJSONArray(int[] ports) {
JSONArray jsonArray = new JSONArray();
for(int i = 0 ; i < ports.length; i++){
jsonArray.add(ports[i]);
}
return jsonArray;
} private int[] JSONArrayToArray(JSONArray jsonArray) throws JSONException {
int size=jsonArray.size();
int[] ports = new int[size];
for(int i = 0 ; i < size; i++){
ports[i] = jsonArray.getInteger(i);
}
return ports;
} }

使用下面的方法对Cookie与String进行相互转换:

private String toJsonString(List<Cookie> cookies) {
CookieMapper cookieMapper = new CookieMapper();
try {
JSONArray jsonArray = new JSONArray();
for (Cookie cookie1 : cookies) {
jsonArray.add(cookieMapper.toJSONObject(cookie1));
}
return jsonArray.toString();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
private Cookie[] getCookiesFromStore(String jsonStr) {
if (jsonStr==null || jsonStr.equals("")) {
return new Cookie[0];
}
CookieMapper cookieMapper = new CookieMapper();
try {
JSONArray jsonArray = JSONArray.parseArray(jsonStr);
List<Cookie> cookies = new ArrayList<Cookie>(jsonArray.size());
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
cookies.add(cookieMapper.toCookie(jsonObject));
}
return cookies.toArray(new Cookie[0]);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
client.setDefaultCookieStore来设置httpclient使用自己的cookieStore

HttpClient 4.3 使用的更多相关文章

  1. HttpClient的替代者 - RestTemplate

    需要的包 ,除了Spring的基础包外还用到json的包,这里的数据传输使用json格式 客户端和服务端都用到一下的包 <!-- Spring --> <dependency> ...

  2. 关于微软HttpClient使用,避免踩坑

    最近公司对于WebApi的场景使用也越来越加大了,随之而来就是Api的客户端工具我们使用哪个?我们最常用的估计就是HttpClient,在微软类库中命名空间地址:System.Net.Http,是一个 ...

  3. 使用HttpClient的优解

    新工作入职不满半周,目前仍然还在交接工作,适应环境当中,笔者不得不说看别人的源码实在是令人痛苦.所幸今天终于将大部分工作流畅地看了一遍,接下来就是熟悉框架技术的阶段了. 也正是在看源码的过程当中,有一 ...

  4. Java的异步HttpClient

    上篇提到了高性能处理的关键是异步,而我们当中许多人依旧在使用同步模式的HttpClient访问第三方Web资源,我认为原因之一是:异步的HttpClient诞生较晚,许多人不知道:另外也可能是大多数W ...

  5. 揭秘Windows10 UWP中的httpclient接口[2]

    阅读目录: 概述 如何选择 System.Net.Http Windows.Web.Http HTTP的常用功能 修改http头部 设置超时 使用身份验证凭据 使用客户端证书 cookie处理 概述 ...

  6. C#中HttpClient使用注意:预热与长连接

    最近在测试一个第三方API,准备集成在我们的网站应用中.API的调用使用的是.NET中的HttpClient,由于这个API会在关键业务中用到,对调用API的整体响应速度有严格要求,所以对HttpCl ...

  7. HttpClient调用webApi时注意的小问题

    HttpClient client = new HttpClient(); client.BaseAddress = new Uri(thisUrl); client.GetAsync("a ...

  8. HttpClient相关

    HTTPClient的主页是http://jakarta.apache.org/commons/httpclient/,你可以在这里得到关于HttpClient更加详细的信息 HttpClient入门 ...

  9. Atitit.http httpclient实践java c# .net php attilax总结

    Atitit.http httpclient实践java c# .net php attilax总结 1. Navtree>> net .http1 2. Httpclient理论1 2. ...

  10. 使用httpclient发送get或post请求

    HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的.最新的.功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建 ...

随机推荐

  1. DIY一个高大上带提醒的计时器,简单实用,你还在等什么

    小编心语:锵锵锵!小编我又来了!昨天发了一篇比较实用的<Python聊天室>,鉴于反响还不错,SO ,小编也想给大家多分享点有用的干货,让大家边学边用.好了,闲话不多说,今天要给各位看官们 ...

  2. 具备 jQuery 经验的人如何学习AngularJS(附:学习路径)

    这是一个来自stackoverflow的问答,三哥直接把最佳回答搬过来了. 都说AngularJS的学习曲线异常诡异~~~ Q: “Thinking in AngularJS” if I have a ...

  3. 迁移Reporting Services的方法与WMI错误

    今天上午,接到一个任务:迁移SQL SERVER 2005的报表服务到另外一台SQL SERVER 2008服务器,结果等我备份了两边服务器的ReportServer,ReportServerTemp ...

  4. 在执行xp_cmdshell的过程中出错,调用'LogonUserW'失败,错误代码:'1909'

    在上篇文章Could not obtain information about Windows NT group/user 'xxxx\xxxx', error code 0x5里面,我介绍了SQL ...

  5. SQLite学习笔记(七)&&事务处理

    说到事务一定会提到ACID,所谓事务的原子性,一致性,隔离性和持久性.对于一个数据库而言,通常通过并发控制和故障恢复手段来保证事务在正常和异常情况下的ACID特性.sqlite也不例外,虽然简单,依然 ...

  6. C# 实现酒店房态图

    酒店管理系统最重要和实用的是能够及时.一目了然的反应房间状态的房态图,之前在开发一个的酒店管理系统中做了一个还算实用的房态图,现在分享下: 鼠标移到每个房间上面,可显示提示信息: 还可以自定义设置不同 ...

  7. [iOS]技巧集锦:UICollectionView内容下沉64像素原因和解决方案

    现象 UICollectionView的内容在按Home键再回到APP时,会下沉64像素. 原因 页面有NavigationBar,正好是64像素,Controller勾选了Adjust Scroll ...

  8. Nginx中的一些匹配顺序

    Nginx中经常需要做各种配置,总结如下: 1.server_name配置 nginx中的server_name指令主要用于配置基于名称虚拟主机,同一个Nginx虚拟主机中,可以绑定多个server_ ...

  9. RabbitMQ服务安装配置

    RabbitMQ是流行的开源消息队列系统,是AMQP(Advanced Message Queuing Protocol高级消息队列协议)的标准实现,用erlang语言开发.RabbitMQ据说具有良 ...

  10. 关于JS的编码转换问题

    在进行JS开发过程中,尤其是在开发报表时,报表已集成到Web页面中,通过在页面传递参数至报表中时,会发现有时某些参数值,传递到报表中是显示为问号或乱码等等一系列不能正常显示的情况. 这是由于浏览器和报 ...