commons httpclient-GET / POST 요청에 쿼리 문자열 매개 변수 추가


79

나는 Spring 서블릿에 대한 http 호출을 만들기 위해 commons HttpClient를 사용하고 있습니다. 쿼리 문자열에 몇 가지 매개 변수를 추가해야합니다. 그래서 다음을 수행합니다.

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을 반환합니다. 사실 parameterMap은 완전히 비어 있습니다. HttpGet 요청을 만들기 전에 매개 변수를 URL에 수동으로 추가하면 매개 변수를 서블릿에서 사용할 수 있습니다. queryString이 추가 된 URL을 사용하여 브라우저에서 서블릿을 쳤을 때도 마찬가지입니다.

여기에 오류가 무엇입니까? httpclient 3.x에서 GetMethod에는 쿼리 문자열을 추가하는 setQueryString () 메서드가 있습니다. 4.x에서 동등한 것은 무엇입니까?

답변:


136

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

32

요청을 만든 후 쿼리 매개 변수를 추가하려면 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);

12

HttpParams인터페이스는 쿼리 문자열 매개 변수를 지정하기위한, 그것은의 런타임 동작 지정하기위한, 거기에없는 HttpClient개체를.

쿼리 문자열 매개 변수를 전달하려면 URL에서 직접 조합해야합니다. 예 :

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

먼저 값을 인코딩해야합니다 (사용 URLEncoder).


3
요청 객체가 이미 생성 된 후에 쿼리 문자열 매개 변수를 추가 할 수있는 방법이 없습니까? 그렇지 않은 경우 요청 메소드 (GET / PUT / POST)에 대해 서블릿에 매개 변수를 전달하는 또 다른 표준 방법이 있습니까?
Oceanic

5

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

이 답변은 더 설명 혜택을 누릴 것
D. 벤 Knoble에게

이 대답은 완전한 URI로 URIBuilder를 초기화하는 방법을 찾을 수 없었기 때문에 내 경우에 매우 유용했습니다 http://myserver/apipath. 그것으로 초기화되면 URIBuilder http://myserver/apipath. URI는 외부에서 제공되었으므로 URIBuilder를 사용하기 위해 수동으로 구문 분석하고 싶지 않았습니다.
nuoritoveri

2

이 방법은 괜찮지 만 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

    }
}

GetMethod? httpclient에서 왔습니까? 질문이 그것에 관한 것이기 때문입니다.
Walfrat

예, org.apache.commons.httpclient.methods에서.
Rahul Saini

아 그래,하지만 지금 org.apache.http.client.methods.HttpGet, 그것은 4.x의에서 3.X 버전의 것 같다
Walfrat

0

이것이 내가 URL 작성기를 구현 한 방법입니다. URL에 대한 매개 변수를 제공하기 위해 하나의 서비스 클래스를 작성했습니다.

public interface ParamsProvider {

    String queryProvider(List<BasicNameValuePair> params);

    String bodyProvider(List<BasicNameValuePair> params);
}

방법의 구현은 다음과 같습니다.

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

URL에 대한 쿼리 매개 변수가 필요할 때 간단히 서비스를 호출하고 빌드합니다. 그 예는 아래와 같습니다.

Class Mock{
@Autowired
ParamsProvider paramsProvider;
 String url ="http://www.google.lk";
// For the query params price,type
 List<BasicNameValuePair> queryParameters = new ArrayList<>();
 queryParameters.add(new BasicNameValuePair("price", 100));
 queryParameters.add(new BasicNameValuePair("type", "L"));
url = url+paramsProvider.queryProvider(queryParameters);
// You can use it in similar way to send the body params using the bodyProvider

}

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.