原博客链接:http://www.cnblogs.com/loveyakamoz/archive/2011/07/21/2113251.html
在特定条件下,也许需要来定制HTTP报文通过线路传递,越过了可能使用的HTTP参数来处理非标准不兼容行为的方式。比如,对于Web爬虫,它可能需要强制HttpClient接受格式错误的响应头部信息,来抢救报文的内容。
通常插入一个自定义的报文解析器的过程或定制连接实现需要几个步骤:
提供一个自定义LineParser/LineFormatter接口实现。如果需要,实现报文解析/格式化逻辑。
class MyLineParser extends BasicLineParser {@Overridepublic 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 {@Overrideprotected HttpMessageParser createResponseParser(final SessionInputBuffer buffer,final HttpResponseFactory responseFactory,final HttpParams params) {return new DefaultResponseParser(buffer,new MyLineParser(),responseFactory,params);}}
为了创建新类的连接,提供一个自定义的ClientConnectionOperator接口实现。如果需要,实现不同的套接字初始化代码。
class MyClientConnectionOperator extendsDefaultClientConnectionOperator {public MyClientConnectionOperator(final SchemeRegistry sr) {super(sr);}@Overridepublic OperatedClientConnection createConnection() {return new MyClientConnection();}}
为了创建新类的连接操作,提供自定义的ClientConnectionManager接口实现。
class MyClientConnManager extends SingleClientConnManager {public MyClientConnManager(final HttpParams params,final SchemeRegistry sr) {super(params, sr);}@Overrideprotected ClientConnectionOperator createConnectionOperator(final SchemeRegistry sr) {return new MyClientConnectionOperator(sr);}}
如果它可以从给定的执行上下文中来获得,UserTokenHandler接口的默认实现是使用主类的一个实例来代表HTTP连接的状态对象。UserTokenHandler将会使用基于如NTLM或开启的客户端认证SSL会话认证模式的用户的主连接。如果二者都不可用,那么就不会返回令牌。
DefaultHttpClient httpclient = new DefaultHttpClient();httpclient.setUserTokenHandler(new UserTokenHandler() {public Object getUserToken(HttpContext context) {return context.getAttribute("my-token");}});
'http.user-token':对象实例代表真实的用户标识,通常期望Principle接口的实例。
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);
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();}