2012-03-28 131 views
41

我正在使用commons HttpClient對Spring servlet進行http調用。我需要在查詢字符串中添加一些參數。所以,我做到以下幾點:commons httpclient - 向GET/POST請求添加查詢字符串參數

HttpRequestBase request = new HttpGet(url); 
HttpParams params = new BasicHttpParams(); 
params.setParameter("key1", "value1"); 
params.setParameter("key2", "value2"); 
params.setParameter("key3", "value3"); 
request.setParams(params); 
HttpClient httpClient = new DefaultHttpClient(); 
httpClient.execute(request); 

然而,當我嘗試使用

((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest().getParameter("key"); 

返回null閱讀在servlet的參數。實際上parameterMap是完全空的。當我在創建HttpGet請求之前手動將參數附加到url時,這些參數在servlet中可用。當我使用追加了queryString的URL從瀏覽器中打開servlet時也是如此。

這裏有什麼錯誤?在httpclient 3.x中,GetMethod有一個setQueryString()方法來追加查詢字符串。 4.x中的等效物是什麼?

回答

61

這裏是你將如何使用的HttpClient 4.2及更高版本添加查詢字符串參數:

URIBuilder builder = new URIBuilder("http://example.com/"); 
builder.setParameter("parts", "all").setParameter("action", "finish"); 

HttpPost post = new HttpPost(builder.build()); 

產生的URI將如下所示:

http://example.com/?parts=all&action=finish 
11

HttpParams接口不用於指定查詢字符串參數,它用於指定HttpClient對象的運行時行爲。

如果您想傳遞查詢字符串參數,您需要自己將它們組裝到URL上,例如,

new HttpGet(url + "key1=" + value1 + ...); 

記得先編碼值(使用URLEncoder)。

+3

有沒有辦法AFTER請求對象已經創建添加查詢字符串參數?如果沒有,是否有另一種標準方法將參數傳遞給servlet以用於任何請求方法(GET/PUT/POST)? – Oceanic 2012-03-28 12:57:25

23

如果你想添加的查詢參數已創建的請求後,嘗試鑄造HttpRequestHttpBaseRequest。然後你可以改變鑄造請求的URI:

HttpGet someHttpGet = new HttpGet("http://google.de"); 

URI uri = new URIBuilder(someHttpGet.getURI()).addParameter("q", 
     "That was easy!").build(); 

((HttpRequestBase) someHttpGet).setURI(uri); 
1

這種方法是可以的,但不適用於動態獲取參數,有時爲1,2,3或更多,就像SOLR搜索查詢(例如)

這是一個更靈活的解決方案。原油,但可以提煉。

public static void main(String[] args) { 

    String host = "localhost"; 
    String port = "9093"; 

    String param = "/10-2014.01?description=cars&verbose=true&hl=true&hl.simple.pre=<b>&hl.simple.post=</b>"; 
    String[] wholeString = param.split("\\?"); 
    String theQueryString = wholeString.length > 1 ? wholeString[1] : ""; 

    String SolrUrl = "http://" + host + ":" + port + "/mypublish-services/carclassifications/" + "loc"; 

    GetMethod method = new GetMethod(SolrUrl); 

    if (theQueryString.equalsIgnoreCase("")) { 
     method.setQueryString(new NameValuePair[]{ 
     }); 
    } else { 
     String[] paramKeyValuesArray = theQueryString.split("&"); 
     List<String> list = Arrays.asList(paramKeyValuesArray); 
     List<NameValuePair> nvPairList = new ArrayList<NameValuePair>(); 
     for (String s : list) { 
      String[] nvPair = s.split("="); 
      String theKey = nvPair[0]; 
      String theValue = nvPair[1]; 
      NameValuePair nameValuePair = new NameValuePair(theKey, theValue); 
      nvPairList.add(nameValuePair); 
     } 
     NameValuePair[] nvPairArray = new NameValuePair[nvPairList.size()]; 
     nvPairList.toArray(nvPairArray); 
     method.setQueryString(nvPairArray);  // Encoding is taken care of here by setQueryString 

    } 
} 
+0

GetMethod?它來自httpclient嗎?因爲這個問題是關於它的。 – Walfrat 2017-01-23 13:52:47

+0

是的,來自org.apache.commons.httpclient.methods。 – 2017-01-23 18:11:02

+0

啊是的,但它似乎是3.x版本,在4.x,現在是org.apache.http.client.methods.HttpGet – Walfrat 2017-01-24 08:35:08

2
I am using httpclient 4.4. For solr query I used the following way and it worked. 

NameValuePair nv2 = new BasicNameValuePair("fq","(active:true) AND (category:Fruit OR category1:Vegetable)"); 
nvPairList.add(nv2); 
NameValuePair nv3 = new BasicNameValuePair("wt","json"); 
nvPairList.add(nv3); 
NameValuePair nv4 = new BasicNameValuePair("start","0"); 
nvPairList.add(nv4); 
NameValuePair nv5 = new BasicNameValuePair("rows","10"); 
nvPairList.add(nv5); 

HttpClient client = HttpClientBuilder.create().build(); 
HttpGet request = new HttpGet(url); 
URI uri = new URIBuilder(request.getURI()).addParameters(nvPairList).build(); 
      request.setURI(uri); 

HttpResponse response = client.execute(request);  
if (response.getStatusLine().getStatusCode() != 200) { 

} 

BufferedReader br = new BufferedReader(
          new InputStreamReader((response.getEntity().getContent()))); 

String output; 
System.out.println("Output .... "); 
String respStr = ""; 
while ((output = br.readLine()) != null) { 
    respStr = respStr + output; 
    System.out.println(output); 
} 
+0

此答案受益於更多解釋 – 2017-01-10 05:07:45

+0

這個答案對我的情況非常有用因爲我找不到用完整URI初始化URIBuilder的方法,例如'http:// myserver/apipath'。當它初始化時,URIBuilder只使用'http:// myserver'並忽略'/ apipath'。 URI是外部提供的,所以我不想爲了使用URIBuilder而手動解析它。 – nuoritoveri 2017-07-04 13:12:59