Как использовать параметры с HttpPost - PullRequest
53 голосов
/ 14 ноября 2011

Я использую веб-сервис RESTfull с этим методом:

@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"} 

Ответы [ 3 ]

99 голосов
/ 15 ноября 2011

Чтобы установить параметры для 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);
4 голосов
/ 15 июня 2016

Вы также можете использовать этот подход в случае, если вы хотите передать некоторые параметры 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();
}
1 голос
/ 14 ноября 2011

Вообще говоря, 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...