HTTP POST с использованием JSON в Java


188

Я хотел бы сделать простой HTTP POST, используя JSON в Java.

Допустим, URL-адрес www.site.com

и он принимает значение, {"name":"myname","age":"20"}помеченное как, 'details'например.

Как бы я пошел о создании синтаксиса для POST?

Я также не могу найти метод POST в JSON Javadocs.

Ответы:


167

Вот что вам нужно сделать:

  1. Получите Apache HttpClient, это позволит вам сделать необходимый запрос
  2. Создайте с ним запрос HttpPost и добавьте заголовок «application / x-www-form-urlencoded»
  3. Создайте StringEntity, который вы передадите ему JSON
  4. Выполнить звонок

Код выглядит примерно так (вам все равно нужно будет его отладить и заставить работать)

//Deprecated
//HttpClient httpClient = new DefaultHttpClient(); 

HttpClient httpClient = HttpClientBuilder.create().build(); //Use this instead 

try {

    HttpPost request = new HttpPost("http://yoururl");
    StringEntity params =new StringEntity("details={\"name\":\"myname\",\"age\":\"20\"} ");
    request.addHeader("content-type", "application/x-www-form-urlencoded");
    request.setEntity(params);
    HttpResponse response = httpClient.execute(request);

    //handle response here...

}catch (Exception ex) {

    //handle exception here

} finally {
    //Deprecated
    //httpClient.getConnectionManager().shutdown(); 
}

9
Вы можете, но всегда полезно абстрагировать его как JSONObject, как будто вы делаете это непосредственно в строке, вы можете неправильно запрограммировать строку и вызвать синтаксическую ошибку. Используя JSONObject, вы убедитесь, что ваша сериализация всегда соответствует правильной структуре JSON
momo

3
В принципе, они оба просто передают данные. Разница лишь в том, как вы обрабатываете это на сервере. Если у вас есть только несколько пар ключ-значение, тогда вполне достаточно обычного параметра POST с ключом key1 = значение1, ключ2 = значение2 и т. Д., Но как только ваши данные станут более сложными и особенно содержат сложную структуру (вложенный объект, массивы), вы захотите начать рассматривать использование JSON. Отправка сложной структуры с использованием пары ключ-значение будет очень неприятной и трудной для анализа на сервере (вы можете попробовать, и вы сразу увидите это). До сих пор помню тот день, когда мы должны были сделать это ... это было не красиво ...
Момо

1
Рад помочь! Если это то, что вы ищете, вы должны принять ответ, чтобы другие люди с похожими вопросами имели хороший ответ на свои вопросы. Вы можете использовать галочку на ответе. Дайте мне знать, если у вас есть дополнительные вопросы
momo

12
Не должен ли тип контента быть 'application / json'. 'application / x-www-form-urlencoded' подразумевает, что строка будет отформатирована аналогично строке запроса. Я вижу, что вы сделали, вы поместили BLOB-объект в качестве значения свойства.
Мэтью Уорд

1
Устаревшую часть следует заменить с помощью метода CloseableHttpClient, который предоставляет метод .close (). См stackoverflow.com/a/20713689/1484047
Frame91

92

Вы можете использовать библиотеку Gson для преобразования ваших классов Java в объекты JSON.

Создайте класс pojo для переменных, которые вы хотите отправить согласно приведенному выше примеру.

{"name":"myname","age":"20"}

становится

class pojo1
{
   String name;
   String age;
   //generate setter and getters
}

как только вы установите переменные в классе pojo1, вы можете отправить это, используя следующий код

String       postUrl       = "www.site.com";// put in your url
Gson         gson          = new Gson();
HttpClient   httpClient    = HttpClientBuilder.create().build();
HttpPost     post          = new HttpPost(postUrl);
StringEntity postingString = new StringEntity(gson.toJson(pojo1));//gson.tojson() converts your pojo to json
post.setEntity(postingString);
post.setHeader("Content-type", "application/json");
HttpResponse  response = httpClient.execute(post);

и это импорт

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;

и для GSON

import com.google.gson.Gson;

1
привет, как вы создаете свой объект httpClient? Это интерфейс
user3290180

1
Да, это интерфейс. Вы можете создать экземпляр, используя 'HttpClient httpClient = new DefaultHttpClient ();'
Пракаш

2
теперь это устарело, мы должны использовать HttpClient httpClient = HttpClientBuilder.create (). build ();
user3290180

5
Как импортировать HttpClientBuilder?
Esterlinkof

3
Я нахожу немного чище использовать параметр ContentType в конструкторе StringUtils и передать ContentType.APPLICATION_JSON вместо ручной настройки заголовка.
TownCube

48

Ответ @ momo для Apache HttpClient версии 4.3.1 или более поздней. Я использую JSON-Javaдля создания моего объекта JSON:

JSONObject json = new JSONObject();
json.put("someKey", "someValue");    

CloseableHttpClient httpClient = HttpClientBuilder.create().build();

try {
    HttpPost request = new HttpPost("http://yoururl");
    StringEntity params = new StringEntity(json.toString());
    request.addHeader("content-type", "application/json");
    request.setEntity(params);
    httpClient.execute(request);
// handle response here...
} catch (Exception ex) {
    // handle exception here
} finally {
    httpClient.close();
}

20

Вероятно, проще всего использовать HttpURLConnection .

http://www.xyzws.com/Javafaq/how-to-use-httpurlconnection-post-data-to-web-server/139

Вы будете использовать JSONObject или что-то еще для создания своего JSON, но не для управления сетью; вам нужно его сериализовать, а затем передать его в HttpURLConnection для POST.


JSONObject j = new JSONObject (); j.put («имя», «мое имя»); j.put («возраст», «20»); Как это? Как мне его сериализовать?
asdf007

@ asdf007 просто используй j.toString().
Алекс Черчилль

Это правда, эта связь блокируется. Это, вероятно, не имеет большого значения, если вы отправляете POST; это гораздо важнее, если вы используете веб-сервер.
Алекс Черчилль

Ссылка HttpURLConnection не работает.
Тобиас Роланд,

Вы можете опубликовать пример, как отправить JSON в тело?

15
protected void sendJson(final String play, final String prop) {
     Thread t = new Thread() {
     public void run() {
        Looper.prepare(); //For Preparing Message Pool for the childThread
        HttpClient client = new DefaultHttpClient();
        HttpConnectionParams.setConnectionTimeout(client.getParams(), 1000); //Timeout Limit
        HttpResponse response;
        JSONObject json = new JSONObject();

            try {
                HttpPost post = new HttpPost("http://192.168.0.44:80");
                json.put("play", play);
                json.put("Properties", prop);
                StringEntity se = new StringEntity(json.toString());
                se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
                post.setEntity(se);
                response = client.execute(post);

                /*Checking response */
                if (response != null) {
                    InputStream in = response.getEntity().getContent(); //Get the data in the entity
                }

            } catch (Exception e) {
                e.printStackTrace();
                showMessage("Error", "Cannot Estabilish Connection");
            }

            Looper.loop(); //Loop in the message queue
        }
    };
    t.start();
}

7
Пожалуйста, отредактируйте ваш пост, чтобы добавить больше объяснения о том, что делает ваш код и почему это решит проблему. Ответ, который в основном содержит только код (даже если он работает), обычно не помогает ОП понять их проблему
Reeno

14

Попробуйте этот код:

HttpClient httpClient = new DefaultHttpClient();

try {
    HttpPost request = new HttpPost("http://yoururl");
    StringEntity params =new StringEntity("details={\"name\":\"myname\",\"age\":\"20\"} ");
    request.addHeader("content-type", "application/json");
    request.addHeader("Accept","application/json");
    request.setEntity(params);
    HttpResponse response = httpClient.execute(request);

    // handle response here...
}catch (Exception ex) {
    // handle exception here
} finally {
    httpClient.getConnectionManager().shutdown();
}

Спасибо! Только ваш ответ решил проблему с кодировкой :)
Shrikant

@SonuDhakar, почему вы отправляете application/jsonкак заголовок подтверждения, так и тип контента
Касун Сиямбалапития,

Кажется, DefaultHttpClientэто устарело.
sdgfsdh

11

Я нашел этот вопрос в поисках решения о том, как отправить почтовый запрос от клиента Java на конечные точки Google. Приведенные выше ответы, скорее всего, правильные, но не работают в случае конечных точек Google.

Решение для конечных точек Google.

  1. Тело запроса должно содержать только строку JSON, а не пару имя = значение.
  2. Заголовок типа контента должен быть установлен на «application / json».

    post("http://localhost:8888/_ah/api/langapi/v1/createLanguage",
                       "{\"language\":\"russian\", \"description\":\"dsfsdfsdfsdfsd\"}");
    
    
    
    public static void post(String url, String json ) throws Exception{
      String charset = "UTF-8"; 
      URLConnection connection = new URL(url).openConnection();
      connection.setDoOutput(true); // Triggers POST.
      connection.setRequestProperty("Accept-Charset", charset);
      connection.setRequestProperty("Content-Type", "application/json;charset=" + charset);
    
      try (OutputStream output = connection.getOutputStream()) {
        output.write(json.getBytes(charset));
      }
    
      InputStream response = connection.getInputStream();
    }

    Это также можно сделать с помощью HttpClient.


8

Вы можете использовать следующий код с Apache HTTP:

String payload = "{\"name\": \"myname\", \"age\": \"20\"}";
post.setEntity(new StringEntity(payload, ContentType.APPLICATION_JSON));

response = client.execute(request);

Кроме того, вы можете создать объект json и вставить поля в объект, как это

HttpPost post = new HttpPost(URL);
JSONObject payload = new JSONObject();
payload.put("name", "myName");
payload.put("age", "20");
post.setEntity(new StringEntity(payload.toString(), ContentType.APPLICATION_JSON));

важно добавить ContentType.APPLICATION_JSON, иначе у меня не получится новый StringEntity (полезная нагрузка, ContentType.APPLICATION_JSON)
Джонни Кейдж

2

Для Java 11 вы можете использовать новый HTTP-клиент :

 HttpClient client = HttpClient.newHttpClient();
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("http://localhost/api"))
        .header("Content-Type", "application/json")
        .POST(ofInputStream(() -> getClass().getResourceAsStream(
            "/some-data.json")))
        .build();

    client.sendAsync(request, BodyHandlers.ofString())
        .thenApply(HttpResponse::body)
        .thenAccept(System.out::println)
        .join();

Вы можете использовать издателя из InputStream, String, File. Преобразование JSON в строку или IS вы можете с Джексоном.


1

Java 8 с Apache httpClient 4

CloseableHttpClient client = HttpClientBuilder.create().build();
HttpPost httpPost = new HttpPost("www.site.com");


String json = "details={\"name\":\"myname\",\"age\":\"20\"} ";

        try {
            StringEntity entity = new StringEntity(json);
            httpPost.setEntity(entity);

            // set your POST request headers to accept json contents
            httpPost.setHeader("Accept", "application/json");
            httpPost.setHeader("Content-type", "application/json");

            try {
                // your closeablehttp response
                CloseableHttpResponse response = client.execute(httpPost);

                // print your status code from the response
                System.out.println(response.getStatusLine().getStatusCode());

                // take the response body as a json formatted string 
                String responseJSON = EntityUtils.toString(response.getEntity());

                // convert/parse the json formatted string to a json object
                JSONObject jobj = new JSONObject(responseJSON);

                //print your response body that formatted into json
                System.out.println(jobj);

            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {

                e.printStackTrace();
            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

0

Я рекомендую http-запрос, основанный на apache http api.

HttpRequest<String> httpRequest = HttpRequestBuilder.createPost(yourUri, String.class)
    .responseDeserializer(ResponseDeserializer.ignorableDeserializer()).build();

public void send(){
   ResponseHandler<String> responseHandler = httpRequest.execute("details", yourJsonData);

   int statusCode = responseHandler.getStatusCode();
   String responseContent = responseHandler.orElse(null); // returns Content from response. If content isn't present returns null. 
}

Если вы хотите отправить JSONкак тело запроса, вы можете:

  ResponseHandler<String> responseHandler = httpRequest.executeWithBody(yourJsonData);

Я настоятельно рекомендую прочитать документацию перед использованием.


почему вы предлагаете это по вышеупомянутому ответу с наибольшим количеством голосов?
Джерил Кук

Потому что это очень просто использовать и делать манипуляции с ответом.
Бено Аракелян
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.