commons httpclient - 将查询字符串参数添加到GET / POST请求

时间:2012-03-28 12:08:16

标签: java apache-httpclient-4.x

我正在使用公共HttpClient对Spring servlet进行http调用。我需要在查询字符串中添加一些参数。所以我做了以下几点:

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);

但是当我尝试使用

读取servlet中的参数时
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest().getParameter("key");

它返回null。实际上parameterMap是完全空的。当我在创建HttpGet请求之前手动将参数附加到url时,参数在servlet中可用。当我使用附加了queryString的URL从浏览器中访问servlet时也是如此。

这里的错误是什么?在httpclient 3.x中,GetMethod有一个setQueryString()方法来追加查询字符串。 4.x中的等价物是什么?

7 个答案:

答案 0 :(得分:97)

以下是使用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

答案 1 :(得分:25)

如果要在创建请求后添加查询参数,请尝试将HttpRequest强制转换为HttpBaseRequest。然后,您可以更改已转换请求的URI:

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

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

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

答案 2 :(得分:12)

HttpParams接口不用于指定查询字符串参数,而是用于指定HttpClient对象的运行时行为。

如果要传递查询字符串参数,则需要自己在URL上组装它们,例如

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

请记住首先对值进行编码(使用URLEncoder)。

答案 3 :(得分:4)

我正在使用httpclient 4.4。

对于solr查询,我使用了以下方法并且它有效。

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);
}

答案 4 :(得分:1)

这种方法还可以,但是当你动态获取params时有效,有时是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

    }
}

答案 5 :(得分:0)

这就是我实施URL构建器的方式。 我创建了一个Service类来提供URL的参数

 @BeforeTest
 public void before()
 {
     if (driver == null)
     {
         // initialize the driver  
     }

 }

方法的实现如下

public interface ParamsProvider {

    String queryProvider(List<BasicNameValuePair> params);

    String bodyProvider(List<BasicNameValuePair> params);
}

当我们需要URL的查询参数时,我只需调用服务并进行构建即可。 下面是示例。

@Component
public class ParamsProviderImp implements ParamsProvider {
    @Override
    public String queryProvider(List<BasicNameValuePair> params) {
        StringBuilder query = new StringBuilder();
        AtomicBoolean first = new AtomicBoolean(true);
        params.forEach(basicNameValuePair -> {
            if (first.get()) {
                query.append("?");
                query.append(basicNameValuePair.toString());
                first.set(false);
            } else {
                query.append("&");
                query.append(basicNameValuePair.toString());
            }
        });
        return query.toString();
    }

    @Override
    public String bodyProvider(List<BasicNameValuePair> params) {
        StringBuilder body = new StringBuilder();
        AtomicBoolean first = new AtomicBoolean(true);
        params.forEach(basicNameValuePair -> {
            if (first.get()) {
                body.append(basicNameValuePair.toString());
                first.set(false);
            } else {
                body.append("&");
                body.append(basicNameValuePair.toString());
            }
        });
        return body.toString();
    }
}

答案 6 :(得分:0)

我使用的是 Java 8 和 apache httpclient 4.5.13

fbq('init', '<PIXEL_A>');
fbq('init', '<PIXEL_B>');
fbq('track', 'PageView'); //fire PageView for both initialized pixels

// only fire the Purchase event for Pixel A
fbq('trackSingle', '<PIXEL_A>', 'Purchase', {
      value: 4,
      currency: 'GBP',
});

// only fire the custom event Step4 for Pixel B
fbq('trackSingleCustom', '<PIXEL_B>', 'Step4',{
  //optional parameters
});

DTO 的完整示例

HashMap<String, String> customParams = new HashMap<>();
customParams.put("param1", "ABC");
customParams.put("param2", "123");

URIBuilder uriBuilder = new URIBuilder(baseURL);

for (String paramKey : customParams.keySet()) {
    uriBuilder.addParameter(paramKey, customParams.get(paramKey));
}

System.out.println(uriBuilder.build().toASCIIString()); // ENCODED URL
System.out.println(uriBuilder.build().toString); // NORMAL URL
public class HttpResponseDTO {
    private Integer statusCode;
    private String body;
    private String errorMessage;
    
    public Integer getStatusCode() {
        return statusCode;
    }
    public void setStatusCode(Integer statusCode) {
        this.statusCode = statusCode;
    }
    public String getBody() {
        return body;
    }
    public void setBody(String body) {
        this.body = body;
    }
    public String getErrorMessage() {
        return errorMessage;
    }
    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }
}