HttpClient 教程6 (高级主题)

第六章 高级主题

6.1 自定义客户端连接

在特定条件下,也许需要来定制HTTP报文通过线路传递,越过了可能使用的HTTP参数来处理非标准不兼容行为的方式。比如,对于Web爬虫,它可能需要强制HttpClient接受格式错误的响应头部信息,来抢救报文的内容。

通常插入一个自定义的报文解析器的过程或定制连接实现需要几个步骤:

提供一个自定义LineParser/LineFormatter接口实现。如果需要,实现报文解析/格式化逻辑。

class MyLineParser extends BasicLineParser {
@Override
public Header parseHeader(
final CharArrayBuffer buffer) throws ParseException {
try {
return super.parseHeader(buffer);
} catch (ParseException ex) {
// 压制ParseException异常
return new BasicHeader("invalid", buffer.toString());
}
}
}

提过一个自定义的OperatedClientConnection实现。替换需要自定义的默认请求/响应解析器,请求/响应格式化器。如果需要,实现不同的报文写入/读取代码。

class MyClientConnection extends DefaultClientConnection {
@Override
protected HttpMessageParser createResponseParser(
final SessionInputBuffer buffer,
final HttpResponseFactory responseFactory,
final HttpParams params) {
return new DefaultResponseParser(buffer,
new MyLineParser(),responseFactory,params);
}
}

为了创建新类的连接,提供一个自定义的ClientConnectionOperator接口实现。如果需要,实现不同的套接字初始化代码。

class MyClientConnectionOperator extends
DefaultClientConnectionOperator {
public MyClientConnectionOperator(
final SchemeRegistry sr) {
super(sr);
}
@Override
public OperatedClientConnection createConnection() {
return new MyClientConnection();
}
}

为了创建新类的连接操作,提供自定义的ClientConnectionManager接口实现。

class MyClientConnManager extends SingleClientConnManager {
public MyClientConnManager(
final HttpParams params,
final SchemeRegistry sr) {
super(params, sr);
}
@Override
protected ClientConnectionOperator createConnectionOperator(
final SchemeRegistry sr) {
return new MyClientConnectionOperator(sr);
}
}

6.2 有状态的HTTP连接

HTTP规范假设session状态信息通常是以HTTP cookie格式嵌入在HTTP报文中的,因此HTTP连接通常是无状态的,这个假设在现实生活中通常是不对的。也有一些情况,当HTTP连接使用特定的用户标识或特定的安全上下文来创建时,因此不能和其它用户共享,只能由该用户重用。这样的有状态的HTTP连接的示例就是NTLM认证连接和使用客户端证书认证的SSL连接。
6.2.1 用户令牌处理器
HttpClient依赖UserTokenHandler接口来决定给定的执行上下文是否是用户指定的。如果这个上下文是用户指定的或者如果上下文没有包含任何资源或关于当前用户指定详情而是null,令牌对象由这个处理器返回,期望唯一地标识当前的用户。用户令牌将被用来保证用户指定资源不会和其它用户来共享或重用。

如果它可以从给定的执行上下文中来获得,UserTokenHandler接口的默认实现是使用主类的一个实例来代表HTTP连接的状态对象。UserTokenHandler将会使用基于如NTLM或开启的客户端认证SSL会话认证模式的用户的主连接。如果二者都不可用,那么就不会返回令牌。

如果默认的不能满足它们的需要,用户可以提供一个自定义的实现:
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.setUserTokenHandler(new UserTokenHandler() {
public Object getUserToken(HttpContext context) {
return context.getAttribute("my-token");
}
});
6.2.2 用户令牌和执行上下文
在HTTP请求执行的过程中,HttpClient添加了下列和用户标识相关的对象到执行上下文中: 'http.user-token':对象实例代表真实的用户标识,通常期望Principle接口的实例。 我们可以在请求被执行后,通过检查本地HTTP上下文的内容,发现是否用于执行请求的连接是有状态的。
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpget = new HttpGet("http://localhost:8080/");
HttpResponse response = httpclient.execute(httpget, localContext);
HttpEntity entity = response.getEntity();
if (entity != null) {
entity.consumeContent();
}
Object userToken = localContext.getAttribute(ClientContext.USER_TOKEN);
System.out.println(userToken);
6.2.2.1 持久化有状态的连接
请注意带有状态对象的持久化连接仅当请求被执行时,相同状态对象被绑定到执行上下文时可以被重用。所以,保证相同上下文重用于执行随后的相同用户,或用户令牌绑定到之前请求执行上下文的HTTP请求是很重要的。
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpContext localContext1 = new BasicHttpContext();
HttpGet httpget1 = new HttpGet("http://localhost:8080/");
HttpResponse response1 = httpclient.execute(httpget1, localContext1);
HttpEntity entity1 = response1.getEntity();
if (entity1 != null) {
entity1.consumeContent();
}
Principal principal = (Principal) localContext1.getAttribute(
ClientContext.USER_TOKEN);
HttpContext localContext2 = new BasicHttpContext();
localContext2.setAttribute(ClientContext.USER_TOKEN, principal);
HttpGet httpget2 = new HttpGet("http://localhost:8080/");
HttpResponse response2 = httpclient.execute(httpget2, localContext2);
HttpEntity entity2 = response2.getEntity();
if (entity2 != null) {
entity2.consumeContent();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HttpClient 是一个开源的 Java HTTP 客户端库,提供了丰富的功能和灵活的配置选项,可以用于发送 HTTP 请求并处理响应。下面是一些 HttpClient高级使用技巧: 1. 连接池管理:通过使用连接池可以复用 HTTP 连接,减少连接建立和关闭的开销。可以使用 HttpClient 的 ConnectionManager 来管理连接池,并设置最大连接数、每个路由的最大连接数等。 2. 请求配置:可以通过 RequestConfig 对象来配置请求的超时时间、代理、重定向等选项。可以设置全局的默认请求配置,也可以为每个请求单独设置配置。 3. 请求拦截器:可以使用请求拦截器对请求进行预处理,例如添加请求头、修改请求体等。可以通过实现 HttpRequestInterceptor 接口来创建自定义的请求拦截器,并将其添加到 HttpClient 的请求拦截器链中。 4. 响应拦截器:可以使用响应拦截器对响应进行处理,例如解析响应体、处理响应头等。可以通过实现 HttpResponseInterceptor 接口来创建自定义的响应拦截器,并将其添加到 HttpClient 的响应拦截器链中。 5. SSL/TLS 支持:HttpClient 提供了对 SSL/TLS 的支持,可以用于发送 HTTPS 请求。可以通过配置 SSLContext、TrustManager 等对象来自定义 SSL/TLS 的行为。 6. 连接重试:可以通过设置 HttpRequestRetryHandler 来启用连接重试功能。可以根据需要自定义重试策略,例如根据异常类型、重试次数等进行判断。 7. 整合 Cookie:HttpClient 支持自动处理 Cookie,可以通过 CookieStore 对象来管理和保存 Cookie。可以将 CookieStore 和 HttpClientBuilder 关联起来,实现对 Cookie 的自动处理。 这些只是 HttpClient 的一部分高级功能,它还提供了更多的功能和选项,可以根据具体需求进行使用和配置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值