Commons httpclient - Добавление параметров строки запроса в запрос GET/POST
Я использую commons HttpClient, чтобы сделать http-вызов сервлета Spring. Мне нужно добавить несколько параметров в строку запроса. Поэтому я делаю следующее:
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. Фактически параметрMap полностью пуст. Когда я вручную добавляю параметры к URL-адресу перед созданием запроса HttpGet, параметры доступны в сервлете. То же самое, когда я ударил сервлет из браузера, используя URL с добавлением queryString.
Какая ошибка здесь? В httpclient 3.x у GetMethod был метод setQueryString(), чтобы добавить запрос. Что эквивалентно в 4.x?
Ответы
Ответ 1
Вот как вы можете добавить параметры строки запроса, используя 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
Ответ 2
Если вы хотите добавить параметр запроса после создания запроса, попробуйте выполнить 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);
Ответ 3
Интерфейс HttpParams
отсутствует для указания параметров строки запроса, для указания поведения во время выполнения объекта HttpClient
.
Если вы хотите передать параметры строки запроса, вам необходимо собрать их по URL-адресу самостоятельно, например.
new HttpGet(url + "key1=" + value1 + ...);
Не забудьте сначала закодировать значения (используя URLEncoder
).
Ответ 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);
}
Ответ 5
Этот подход одобрен, но не работает, когда вы получаете параметры динамически, иногда 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
}
}
Ответ 6
Вот как я реализовал мой конструктор URL.
Я создал один класс Service для предоставления параметров для 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
}