Подтвердить что ты не робот

Как использовать параметры с 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"} 
4b9b3361

Ответ 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.