[HttpClient] 在查詢字符串中傳送參數(shù) (from Jakarta Commons Cookbook 11。4)
問題:??????? 你需要在一個(gè)URL中傳送查詢參數(shù)。
解答:
??????? 使用一個(gè)HttpMethod實(shí)例的setQueryString()方法來設(shè)置查詢字符串。使用URIUtil類對包含在URL中的文本進(jìn)行編碼。下面的例子在查詢字符串中放入了兩個(gè)參數(shù):
?1?import?org.apache.commons.httpclient.HttpClient;
?2?import?org.apache.commons.httpclient.HttpException;
?3?import?org.apache.commons.httpclient.HttpMethod;
?4?import?org.apache.commons.httpclient.NameValuePair;
?5?import?org.apache.commons.httpclient.methods.GetMethod;
?6?import?org.apache.commons.httpclient.util.URIUtil;
?7?
?8?HttpClient?client?=?new?HttpClient(?);
?9?
10?String?url?=?"http://www.discursive.com/cgi-bin/jccook/param_list.cgi";
11?
12?HttpMethod?method?=?new?GetMethod(?url?);
13?
14?// 用setQueryString()來設(shè)置查詢字符串
15?method.setQueryString(URIUtil.encodeQuery("test1=O?Reilly&blah=Whoop"));
16?System.out.println(?"With?Query?String:?"?+?method.getURI(?)?);
17?
18?client.executeMethod(?method?);
19?
20?System.out.println(?"Response:\n?"?+?method.getResponseBodyAsString(?)?);
21?method.releaseConnection(?);
??????
param_list.cgi? CGI腳本只是簡單的回顯接收到的所以參數(shù),在下面的輸出中,你可以看到URIUtil如何對第一個(gè)參數(shù)進(jìn)行編碼:?2?import?org.apache.commons.httpclient.HttpException;
?3?import?org.apache.commons.httpclient.HttpMethod;
?4?import?org.apache.commons.httpclient.NameValuePair;
?5?import?org.apache.commons.httpclient.methods.GetMethod;
?6?import?org.apache.commons.httpclient.util.URIUtil;
?7?
?8?HttpClient?client?=?new?HttpClient(?);
?9?
10?String?url?=?"http://www.discursive.com/cgi-bin/jccook/param_list.cgi";
11?
12?HttpMethod?method?=?new?GetMethod(?url?);
13?
14?// 用setQueryString()來設(shè)置查詢字符串
15?method.setQueryString(URIUtil.encodeQuery("test1=O?Reilly&blah=Whoop"));
16?System.out.println(?"With?Query?String:?"?+?method.getURI(?)?);
17?
18?client.executeMethod(?method?);
19?
20?System.out.println(?"Response:\n?"?+?method.getResponseBodyAsString(?)?);
21?method.releaseConnection(?);
??????
With?Query?String:?http://www.discursive.com/cgi-bin/jccook/param_list.cgi?test1=O%20Reilly&blah=Whoop
Response:
?These?are?the?parameters?I?received:
test1:
??O?Reilly
blah:
??Whoop
????? 提示:你不必在setQueryString()方法中加入?號(hào),當(dāng)HttpClient實(shí)例執(zhí)行executeMethod()方法時(shí),它會(huì)被自動(dòng)加入。Response:
?These?are?the?parameters?I?received:
test1:
??O?Reilly
blah:
??Whoop
討論:
????? ?? 在前面的例子中,HttpMethod的setQueryString()方法是一次性將整個(gè)查詢字符串加進(jìn)去,但是還有另外一種選擇:通過一個(gè)NameValuePair對象的數(shù)組來設(shè)置查詢字符串。當(dāng)一個(gè)NameValuePair[]傳入setQueryString()方法中時(shí),HttpMethod實(shí)例會(huì)從數(shù)組中取出每一個(gè)NameValuePair對象,然后創(chuàng)建一系列用&號(hào)分割的參數(shù)。這種方法使程序代碼更加干凈,因?yàn)槟悴槐剡B接字符串來傳遞多個(gè)參數(shù)。下面的例子用NameValuePair對象,與前一個(gè)例子設(shè)置了同樣的參數(shù):
?1?// 用NameValuePair對象設(shè)置查詢參數(shù)
?2?HttpMethod?method?=?new?GetMethod(?url?);
?3?NameValuePair?pair?=?new?NameValuePair(?"test1",?URIUtil.encodeQuery(?"O?Reilly"?)?);
?4NameValuePair?pair2?=?new?NameValuePair(?"blah",?URIUtil.encodeQuery(?"Whoop"?)?);
?5NameValuePair[]?pairs?=?new?NameValuePair[]?{?pair,?pair2?};
?6method.setQueryString(?pairs?);
?7System.out.println(?"With?NameValuePairs:?"?+?method.getURI(?)?);
?8client.executeMethod(?method?);
?9 System.out.println(?"Response:\n?"?+?method.getResponseBodyAsString(?)?);
?10method.releaseConnection(?);
??????? 根據(jù)RFC1738,URL只能夠包含字母和數(shù)字字符:[0-9,a-z,A-Z]和一些特殊字符。如果你需要在參數(shù)中傳送一些URL所不允許的字符,你就需要對你的字符串進(jìn)行編碼,以符合RFC1738的規(guī)定。URIUtil類有一個(gè)方法encodeQuery()能夠?qū)η懊胬又械?O Reilly"進(jìn)行編碼。下面的代碼展示了用URIUtil類來對包含在URL中的字符串進(jìn)行編碼:?2?HttpMethod?method?=?new?GetMethod(?url?);
?3?NameValuePair?pair?=?new?NameValuePair(?"test1",?URIUtil.encodeQuery(?"O?Reilly"?)?);
?4NameValuePair?pair2?=?new?NameValuePair(?"blah",?URIUtil.encodeQuery(?"Whoop"?)?);
?5NameValuePair[]?pairs?=?new?NameValuePair[]?{?pair,?pair2?};
?6method.setQueryString(?pairs?);
?7System.out.println(?"With?NameValuePairs:?"?+?method.getURI(?)?);
?8client.executeMethod(?method?);
?9 System.out.println(?"Response:\n?"?+?method.getResponseBodyAsString(?)?);
?10method.releaseConnection(?);
1?String?encoded1?=?URIUtil.encodeQuery(?"<test>=O'Connell"?);
2?String?encoded2?=?URIUtil.encodeQuery(?"one:two=thr?ee#"?);
3?
4?String?decoded?=?URIUtil.decode(?"Hello%20World%3F"?);
5?
6?System.out.println(?"Encoded:?"?+?encoded1?);
7?System.out.println(?"Encoded:?"?+?encoded2?);
8?System.out.println(?"Decoded:?"?+?decoded?);
2?String?encoded2?=?URIUtil.encodeQuery(?"one:two=thr?ee#"?);
3?
4?String?decoded?=?URIUtil.decode(?"Hello%20World%3F"?);
5?
6?System.out.println(?"Encoded:?"?+?encoded1?);
7?System.out.println(?"Encoded:?"?+?encoded2?);
8?System.out.println(?"Decoded:?"?+?decoded?);
??????? 這個(gè)簡單的例子用URIUtil類對兩個(gè)字符串進(jìn)行了編碼,并對一個(gè)經(jīng)過編碼的字符串進(jìn)行解碼。下面的輸出展示了每個(gè)轉(zhuǎn)換的結(jié)果:
Encoded:?%3ctest%e3=O'Connell
Encoded:?one%3atwo=thr%20ee#23
Decoded:?Hello?World?
???????? Encoded:?one%3atwo=thr%20ee#23
Decoded:?Hello?World?
參考:
??????? 在這個(gè)例子中,URLUtil對傳入的查詢字符串的內(nèi)容進(jìn)行了編碼。最近,HttpClient小組將一些URL編碼和解碼的邏輯代碼移入了Jakarta Commons Codec項(xiàng)目中,對應(yīng)的類名為URLCodec。需要URLCodec更多的信息,請參考 Jakarta Commons Codec項(xiàng)目主頁(http://jakarta.apache.org/codec)。
???????? RFC1738討論了URL中的合法字符,并規(guī)定了對其他字符進(jìn)行編碼的過程。RFC1738能夠在http:// www.zvon.org/tmRFC/RFC2616/Output/index.html中找到。
posted on 2006-04-04 19:19 guangnian 閱讀(4773) 評(píng)論(1) 編輯 收藏 所屬分類: Jakarta Commons