6.1 自定義客戶端連接
在特定條件下,也許需要來定制HTTP報文通過線路傳遞,越過了可能使用的HTTP參數(shù)來處理非標(biāo)準(zhǔn)不兼容行為的方式。比如,對于Web爬蟲,它可能需要強制HttpClient接受格式錯誤的響應(yīng)頭部信息,來搶救報文的內(nèi)容。
通常插入一個自定義的報文解析器的過程或定制連接實現(xiàn)需要幾個步驟:
提供一個自定義LineParser/LineFormatter接口實現(xiàn)。如果需要,實現(xiàn)報文解析/格式化邏輯。
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實現(xiàn)。替換需要自定義的默認請求/響應(yīng)解析器,請求/響應(yīng)格式化器。如果需要,實現(xiàn)不同的報文寫入/讀取代碼。
class MyClientConnection extends DefaultClientConnection {@Overrideprotected HttpMessageParser createResponseParser(final SessionInputBuffer buffer,final HttpResponseFactory responseFactory,final HttpParams params) {return new DefaultResponseParser(buffer,new MyLineParser(),responseFactory,params);}}
為了創(chuàng)建新類的連接,提供一個自定義的ClientConnectionOperator接口實現(xiàn)。如果需要,實現(xiàn)不同的套接字初始化代碼。
class MyClientConnectionOperator extendsDefaultClientConnectionOperator {public MyClientConnectionOperator(final SchemeRegistry sr) {super(sr);}@Overridepublic OperatedClientConnection createConnection() {return new MyClientConnection();}}
為了創(chuàng)建新類的連接操作,提供自定義的ClientConnectionManager接口實現(xiàn)。
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);}}
6.2 有狀態(tài)的HTTP連接
6.2.1 用戶令牌處理器
如果它可以從給定的執(zhí)行上下文中來獲得,UserTokenHandler接口的默認實現(xiàn)是使用主類的一個實例來代表HTTP連接的狀態(tài)對象。UserTokenHandler將會使用基于如NTLM或開啟的客戶端認證SSL會話認證模式的用戶的主連接。如果二者都不可用,那么就不會返回令牌。
DefaultHttpClient httpclient = new DefaultHttpClient();httpclient.setUserTokenHandler(new UserTokenHandler() {public Object getUserToken(HttpContext context) {return context.getAttribute("my-token");}});
6.2.2 用戶令牌和執(zhí)行上下文
'http.user-token':對象實例代表真實的用戶標(biāo)識,通常期望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);
6.2.2.1 持久化有狀態(tài)的連接
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();}
轉(zhuǎn)載自:http://www.cnblogs.com/loveyakamoz/archive/2011/07/21/2113251.html