999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

淺析中文環境下的Apach Commons HttpClient編程

2008-12-31 00:00:00田支斌
電腦知識與技術 2008年22期

摘要:本文詳盡的分析了在中文環境下運用Apach Commons HttpClient進行編程時出現的幾個常見問題。針對每個問題,本文均給出較為完善的解決方案,對中文環境下的Apach Commons HttpClient編程具有極大的現實參考價值。

關鍵詞:Apach Commons HttpClient、程序設計、中文操作系統

中圖分類號:TP393文獻標識碼:A文章編號:1009-3044(2008)22-782-02

Analyses of Apach Commons HttpClient Programming in Chinese OS Platform

HONG Liang,TIAN Zhi-bin

(Hunan Normal University, Changsha 410081, China)

Abstract: The paper describes some common problems with Apach Commons HttpClient programming in Chinese OS platform. To every problem,the paper gives preferable solution which may be helpful to Apach Commons HttpClient programming.

Key words: apach commons HttpClient; programming; Chinese OS platform

1 Commons HttpClient開源項目簡介

Http協議是一種應用十分廣泛的網絡應用層協議。在Java網絡編程中我們會經常碰到Http協議編程,雖然JDK提供了HttpURLConnection編程接口對Http協議進行支持,但是由于協議應用本身的復雜性,使得在大量實際項目單純使用JDK進行Http編程仍然相對比較困難。針對這種情況,開源軟件組織Apach推出了HttpClient開源組件,并且提供穩定持續的升級版本,因此在實際項目中采用HttpClient組件進行Http協議編程是一種高效經濟的解決方案。

2 Commons HttpClient中文環境下編程常見問題

由于HttpClient組件設計的高度靈活性及易用性,應用HttpClient組件進行編程本身并不復雜。但是由于Java編程環境自身容易出現字符編碼問題,衍生于Java語言并主要由英語語系國家技術人員推出的HttpClient組件自然在中文環境中會存在一定的編碼問題,同時由于部分Web瀏覽器及Web服務器并未嚴格實現標準Http協議規范,使得比較嚴格遵循標準Http協議規范的HttpClient組件在與部分瀏覽器及服務器進行交互時會出現少量兼容性問題。筆者在中文環境下用HttpClinet開發校外資源訪問系統的過程中碰到系列HttpClient技術問題,經過測試查證找到相應的解決辦法,這對解決HttpClient編程問題,特別是中文環境下HttpClient編程具有較大的借鑒作用。(注:本文編程的HttpClient組件版本為:Release 3.1 Beta 1)

3 Commons HttpClient編程的典型問題及解決辦法

3.1 URL中文參數無法識別的問題

通常情況在Commons HttpClient編程中我們用下列語句就可以向一個目標服務器提交一個Web請求:

HttpClient client=new HttpClient();

GetMethod method = new GetMethod(url);//本示例使用Get方法,當然也可使用Post方法PostMethod method//=new PostMethod(url);

client.executeMethod(method);

InputStream receiver=method.getResponseBodyAsStream();

如果URL沒有中文參數,以上語句執行起來沒有任何問題,但是如果URL中含有中文字符,中文參數將無法被Web服務器識別,程序雖然可以正常運行,但卻無法得到正確結果。同時返回的Http響應頭,如果含有中文字符也將出現亂碼。分析源碼發現,這是HttpClient中的HttpElementCharset參數(創建HTTP headers的字符集)的默認值為US-ASCII,ContentCharset參數(創建content body的字符集)的默認值為ISO-8859-1的原故,因此需要使用下列語句改變這些參數的默認值:

client = new HttpClient();

params=client.getParams();

params.setHttpElementCharset(\"GBK\");

params.setContentCharset(\"GBK\");

或者使用:

method.getParams().setHttpElementCharset(\"GBK\");

method.getParams().setCredentialCharset(\"GBK\");

method.getParams().setContentCharset(\"GBK\");

第一種方式可能會更好,它在HttpClient初始化時就對字符默認參數進行了設置,作用范圍更廣。第二種方式僅對使用具體的請求方法時起作用,字符集的作用范圍有限。一般情況下我們用上述語句即可實現中文字符的正確識別。但要深入使用我們會發現如果URL中文參數含有中文特殊字符(如“{”,“}”等符號),程序將拋出URIException異常,導致請求無法完成。繼續研究HttpClient的源代碼發現,URI類是負責解析URL的核心類,控制URL編碼字符集是ProtocolCharset參數,默認情況下為UTF-8編碼,同時還在URI的構造函數提供了一個邏輯值來決定是否過濾非法字符,而恰恰一些中文特殊字符也被當成非法的字符過濾掉了,根據產生問題的原因,我們在基本解決中文編碼問題的基礎上結合以下容錯的方法來最終保證中文編碼的正確識別:

String url=….;

try

{strUri=new URI(uri,true,\"GBK\");}

catch(URIException e)

{strUri=new URI(uri,1,\"GBK\");}

method.setURI(strUri);

經測試上述辦法解決大量的已知URL中文參數不能識別的問題,當然如果在程序個別地方上述方法依然不能奏效,你還可以使用Java中文編碼轉換的基礎解決方法,借助ISO-8859-1標準編碼過渡,能夠輕易將JVM在網絡傳送過程轉換成的UTF8編碼還原成GBK編碼,下面的代碼實現了這一功能:

byte [] b;

String utf8_value;

utf8_value = request.getParameter(\"NAME\");//從HTTP流中取\"NAME\"的UTF8數據

b = utf8_value.getBytes(\"8859_1\"); //中間用ISO-8859-1過渡

String name = new String(b, \"GB2312\"); //轉換成GB2312字符

3.2 URL中的%問題

部分不太規范的中文網站中使用%作URL中參數的一部分傳遞給服務器,而中文Windows中的許多主流瀏覽器也兼容這一例外。事實上%是作為Http協議中的UrlEncode編碼的保留字符不能直接在URL中使用,必須被轉義成%25這樣的形式,事實上HttpClient就會自動將字符%轉化成%25。正是這種原因當HttpClient截獲IE瀏覽器的請求并將其轉發到服務器時,將會導致查詢參數錯誤。分析HttpClient的源碼發現,這一轉化是在URI類中實現的,經反復測試未能找到一種通過HttpClient公開接口實現這一兼容性的方法。目前只能采取修改URI類源碼重新編譯的辦法來實現:

public static final BitSet allowed_query = new BitSet(256);

// Static initializer for allowed_query

static {

allowed_query.or(uric);

allowed_query.clear('%');將源碼中此語句去掉或注釋即可}

3.3 Cookie整合問題

IE和Firefox在發送請求給服務器時會把所有的cookie打包成一個,然后在這個cookie里按照分號把每一項隔開,中間有個空格。但httpclient會在header里構建多個cookie項,每一項只含有一個cookie,這同IE是不一樣的。為了使用IE這種發送方式,我們需要設置一個請求方法中的一個Cookie參數,參考設置如下:

method.getParams().setParameter(HttpMethodParams.SINGLE_COOKIE_HEADER,new Boolean(true)); //使多個cookie合并成一個cookie頭

3.4 chunked編碼不規范的問題

有時候Web服務器生成HTTP Response是無法在Header就確定消息大小的,這時一般來說服務器將不會提供Content-Length的頭信息,而采用Chunked編碼動態的提供body內容的長度。 Chunked編碼使用若干個Chunk串連而成,由一個標明長度為0的chunk標示結束。使用十分廣泛的Tomcat Web服務器大量采用了Chunked編碼方案,然而早期的Tomcat Web服務器實現并不十分規范,并沒有以標明長度為0的chunk標示內容傳輸結束。因此HttpClient在接收這些早期的Tomcat Web服務器的Http響就會導致解析錯誤。分析HttpClient源碼發現,ChunkedInputStream類負責在HttpClient中解析chunked編碼,修改一個此類中getChunkSizeFromInputStream(final InputStream in)方法,可使標準的和上述非標準的chunked編碼均可正常解析。具體修改方法如下:

private static int getChunkSizeFromInputStream(final InputStream in)

throws IOException {

ByteArrayOutputStream baos = new ByteArrayOutputStream();

// States: 0=normal, 1=\\r was scanned, 2=inside quoted string, -1=end

int state = 0;

while (state != -1) {

int b = in.read();

if (b == -1) {

return 0;//新增加語句

throw new IOException(\"chunked stream ended unexpectedly\");//原始語句,需將其去掉或注釋掉}

3.5 Host頭無法修改的問題

HttpClient本身在HttpMethodBase類中提供增加和修改Http請求頭的addRequestHeader和setRequestHeader方法,然而卻無法修改Host參數,而在一此特殊的場合又要求修改這一參數。經分析源碼發現,HttpClient在設置Http請求頭設計成了不能修改的固定模式。因此為適應特殊要求,只能修改和重編譯HttpMethodBase類。具體修改方法如下:

protected void addRequestHeaders(HttpState state, HttpConnection conn)

throws IOException, HttpException {

LOG.trace(\"enter HttpMethodBase.addRequestHeaders(HttpState, \"

+ \"HttpConnection)\");

addUserAgentRequestHeader(state, conn);

addHostRequestHeader(state, conn); //原始語句,需將其去掉或注釋掉

addCookieRequestHeader(state, conn);

addProxyConnectionHeader(state, conn);}

參考文獻:

[1] Hypertext Transfer Protocol-HTTP/1.1[S/OL].RFC2068.1997-01.http://jakarta.apache.orglcommons/http-client/userguide.html.

[2] Apache Jakarta Common HttpClient[EB/OL].(2004-03).http://jakarta.apache.org/commons/httpclient/userguide.html.

[3] Apach Commons HttpClient [EB/OL].(2007-02).http://jakarta.apache.org/commons/httpclient

[4] HttpClient入門[EB/OL].(2006-12).http://www.ibm.com/developerworks/cn/opensource/os-httpclient/

[5] Harold E R,著.Java網絡編程[M].朱濤江,林劍,譯.北京:中國電力出版社,2005.

主站蜘蛛池模板: 一级毛片在线免费视频| 亚洲一区二区三区国产精华液| 国产成人高精品免费视频| 国产色网站| 思思热在线视频精品| 99这里只有精品免费视频| 亚洲AⅤ综合在线欧美一区| 精品国产一二三区| 色婷婷天天综合在线| 亚洲一级无毛片无码在线免费视频| 五月天福利视频| 91视频首页| 色悠久久久久久久综合网伊人| 国产精品黄色片| 伊人久综合| 午夜福利在线观看入口| 无码内射在线| 免费无遮挡AV| 精品一區二區久久久久久久網站| 国产h视频在线观看视频| 欧美日韩v| 伊人色婷婷| 国产成人8x视频一区二区| 欧美成人一级| 日韩精品亚洲人旧成在线| 国产爽爽视频| 欧美亚洲第一页| 日韩在线网址| 青草视频久久| 国产精品人人做人人爽人人添| 在线va视频| 九月婷婷亚洲综合在线| 欧美午夜视频| 国产浮力第一页永久地址 | 欧美亚洲国产视频| 99热在线只有精品| 国产18在线| 国产主播福利在线观看| 久久美女精品| 国产成人一区二区| 亚洲一区网站| 高清无码手机在线观看| 久精品色妇丰满人妻| 91福利在线看| 国产精品久久久久久久久kt| 国产屁屁影院| 亚洲无码高清一区| 一本色道久久88| 97成人在线视频| 18黑白丝水手服自慰喷水网站| 亚洲福利网址| 91九色视频网| 狠狠色综合久久狠狠色综合| 波多野结衣在线一区二区| 欧美日韩在线观看一区二区三区| 91小视频在线观看| 久操线在视频在线观看| 国产一级视频在线观看网站| 亚洲男人天堂网址| 久久久久久久蜜桃| 国产精品免费入口视频| 亚洲一级毛片在线观播放| 色欲不卡无码一区二区| 久久精品电影| 伊人91在线| 国产欧美日韩精品综合在线| 成人在线观看一区| 99在线免费播放| 天天爽免费视频| 国产欧美日韩精品第二区| 久久伊伊香蕉综合精品| 国产XXXX做受性欧美88| 2021最新国产精品网站| 毛片免费高清免费| 狠狠色婷婷丁香综合久久韩国| 日韩美一区二区| 国产一级裸网站| 免费人欧美成又黄又爽的视频| 久久香蕉国产线看观看精品蕉| 69国产精品视频免费| 免费人成又黄又爽的视频网站| 久久综合伊人 六十路|