Как использовать параметры с HttpPost
Я использую RESTfull webservice с этим методом:
@POST
@Consumes({"application/json"})
@Path("create/")
public void create(String str1, String str2){
System.out.println("value 1 = " + str1);
System.out.println("value 2 = " + str2);
}
В моем приложении Android я хочу вызвать этот метод. Как предоставить правильные значения параметрам с помощью org.apache.http.client.methods.HttpPost;
Я заметил, что могу использовать аннотацию @HeaderParam и просто добавлять заголовки к объекту HttpPost. Правильно ли это? Делать это как:
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("str1", "a value");
httpPost.setHeader("str2", "another value");
Использование метода setEntity на httpPost не будет работать. Он устанавливает только параметр str1 с помощью строки json. При использовании его как:
JSONObject json = new JSONObject();
json.put("str1", "a value");
json.put("str2", "another value");
HttpEntity e = new StringEntity(json.toString());
httpPost.setEntity(e);
//server output: value 1 = {"str1":"a value","str2":"another value"}
Ответы
Ответ 1
Чтобы установить параметры в HttpPostRequest
, вы можете использовать BasicNameValuePair
, что-то вроде этого:
HttpClient httpclient;
HttpPost httppost;
ArrayList<NameValuePair> postParameters;
httpclient = new DefaultHttpClient();
httppost = new HttpPost("your login link");
postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("param1", "param1_value"));
postParameters.add(new BasicNameValuePair("param2", "param2_value"));
httpPost.setEntity(new UrlEncodedFormEntity(postParameters, "UTF-8"));
HttpResponse response = httpclient.execute(httpPost);
Ответ 2
Вы также можете использовать этот подход, если хотите передать некоторые параметры http и отправить запрос json:
(примечание: я добавил в какой-то дополнительный код только то, что он помогает любым другим будущим читателям)
public void postJsonWithHttpParams() throws URISyntaxException, UnsupportedEncodingException, IOException {
//add the http parameters you wish to pass
List<NameValuePair> postParameters = new ArrayList<>();
postParameters.add(new BasicNameValuePair("param1", "param1_value"));
postParameters.add(new BasicNameValuePair("param2", "param2_value"));
//Build the server URI together with the parameters you wish to pass
URIBuilder uriBuilder = new URIBuilder("http://google.ug");
uriBuilder.addParameters(postParameters);
HttpPost postRequest = new HttpPost(uriBuilder.build());
postRequest.setHeader("Content-Type", "application/json");
//this is your JSON string you are sending as a request
String yourJsonString = "{\"str1\":\"a value\",\"str2\":\"another value\"} ";
//pass the json string request in the entity
HttpEntity entity = new ByteArrayEntity(yourJsonString.getBytes("UTF-8"));
postRequest.setEntity(entity);
//create a socketfactory in order to use an http connection manager
PlainConnectionSocketFactory plainSocketFactory = PlainConnectionSocketFactory.getSocketFactory();
Registry<ConnectionSocketFactory> connSocketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", plainSocketFactory)
.build();
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(connSocketFactoryRegistry);
connManager.setMaxTotal(20);
connManager.setDefaultMaxPerRoute(20);
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setSocketTimeout(HttpClientPool.connTimeout)
.setConnectTimeout(HttpClientPool.connTimeout)
.setConnectionRequestTimeout(HttpClientPool.readTimeout)
.build();
// Build the http client.
CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(connManager)
.setDefaultRequestConfig(defaultRequestConfig)
.build();
CloseableHttpResponse response = httpclient.execute(postRequest);
//Read the response
String responseString = "";
int statusCode = response.getStatusLine().getStatusCode();
String message = response.getStatusLine().getReasonPhrase();
HttpEntity responseHttpEntity = response.getEntity();
InputStream content = responseHttpEntity.getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = buffer.readLine()) != null) {
responseString += line;
}
//release all resources held by the responseHttpEntity
EntityUtils.consume(responseHttpEntity);
//close the stream
response.close();
// Close the connection manager.
connManager.close();
}
Ответ 3
Вообще говоря, HTTP POST предполагает, что содержимое тела содержит ряд пар ключ/значение, которые создаются (чаще всего) формой на стороне HTML. Вы не устанавливаете значения с помощью setHeader, так как это не помещает их в тело содержимого.
Итак, с вашим вторым тестом проблема, с которой вы сталкиваетесь, заключается в том, что ваш клиент не создает несколько пар ключ/значение, он только создал один и который по умолчанию был сопоставлен с первым аргументом в вашем методе.
Есть несколько вариантов, которые вы можете использовать. Во-первых, вы можете изменить свой метод, чтобы принять только один входной параметр, а затем передать строку JSON, как и во втором тесте. Внутри метода вы затем разбираете строку JSON в объект, который разрешает доступ к полям.
Другой вариант - определить класс, представляющий поля входных типов, и сделать это единственным входным параметром. Например
class MyInput
{
String str1;
String str2;
public MyInput() { }
// getters, setters
}
@POST
@Consumes({"application/json"})
@Path("create/")
public void create(MyInput in){
System.out.println("value 1 = " + in.getStr1());
System.out.println("value 2 = " + in.getStr2());
}
В зависимости от используемой структуры REST она должна обрабатывать де-сериализацию JSON для вас.
Последний вариант состоит в том, чтобы построить тело POST, которое выглядит следующим образом:
str1=value1&str2=value2
затем добавьте дополнительные аннотации к вашему серверному методу:
public void create(@QueryParam("str1") String str1,
@QueryParam("str2") String str2)
@QueryParam не имеет значения, находится ли поле в сообщении формы или в URL-адресе (например, в запросе GET).
Если вы хотите продолжить использование отдельных аргументов на входе, тогда ключ генерирует запрос клиента для предоставления именованных параметров запроса либо в URL (для GET), либо в теле POST.