6.1 自定義客戶端連接
在特定條件下,也許需要來(lái)定制HTTP報(bào)文通過線路傳遞,越過了可能使用的HTTP參數(shù)來(lái)處理非標(biāo)準(zhǔn)不兼容行為的方式。比如,對(duì)于Web爬蟲,它可能需要強(qiáng)制HttpClient接受格式錯(cuò)誤的響應(yīng)頭部信息,來(lái)?yè)尵葓?bào)文的內(nèi)容。
通常插入一個(gè)自定義的報(bào)文解析器的過程或定制連接實(shí)現(xiàn)需要幾個(gè)步驟:
提供一個(gè)自定義LineParser/LineFormatter接口實(shí)現(xiàn)。如果需要,實(shí)現(xiàn)報(bào)文解析/格式化邏輯。
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());}}}
提過一個(gè)自定義的OperatedClientConnection實(shí)現(xiàn)。替換需要自定義的默認(rèn)請(qǐng)求/響應(yīng)解析器,請(qǐng)求/響應(yīng)格式化器。如果需要,實(shí)現(xiàn)不同的報(bào)文寫入/讀取代碼。
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)建新類的連接,提供一個(gè)自定義的ClientConnectionOperator接口實(shí)現(xiàn)。如果需要,實(shí)現(xiàn)不同的套接字初始化代碼。
class MyClientConnectionOperator extendsDefaultClientConnectionOperator {public MyClientConnectionOperator(final SchemeRegistry sr) {super(sr);}@Overridepublic OperatedClientConnection createConnection() {return new MyClientConnection();}}
為了創(chuàng)建新類的連接操作,提供自定義的ClientConnectionManager接口實(shí)現(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í)行上下文中來(lái)獲得,UserTokenHandler接口的默認(rèn)實(shí)現(xiàn)是使用主類的一個(gè)實(shí)例來(lái)代表HTTP連接的狀態(tài)對(duì)象。UserTokenHandler將會(huì)使用基于如NTLM或開啟的客戶端認(rèn)證SSL會(huì)話認(rèn)證模式的用戶的主連接。如果二者都不可用,那么就不會(huì)返回令牌。
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':對(duì)象實(shí)例代表真實(shí)的用戶標(biāo)識(shí),通常期望Principle接口的實(shí)例。
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