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 = value1, key2 = value2 і т.д., ймовірно, достатньо, але як тільки ваші дані будуть складнішими і особливо містять складну структуру (вкладений об'єкт, масиви), ви б хотіли почніть розглянути можливість використання JSON. Надіслати складну структуру за допомогою пари ключ-значення буде дуже неприємно і важко проаналізувати на сервері (ви можете спробувати, і ви побачите це відразу). Ще пам’ятайте той день, коли нам довелося робити це угр .. це було не дуже ..
momo

1
Радий допомогти! Якщо це те, що ви шукаєте, ви повинні прийняти відповідь, щоб інші люди з подібними питаннями добре поводилися на їх питання. Ви можете використовувати галочку у відповіді. Повідомте мене, якщо у вас є додаткові запитання
momo

12
Чи не повинен тип вмісту бути "application / json". 'application / x-www-form-urlencoded' означає, що рядок буде форматований аналогічно рядку запиту. NM Я бачу, що ви зробили, ви поставили json 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 ();
користувач3290180

5
Як імпортувати HttpClientBuilder?
Естерлінкоф

3
Мені здається, дещо чіткіше використовувати параметр ContentType в конструкторі StringUtils та передавати його в ContentType.APPLICATION_JSON замість ручного встановлення заголовка.
TownCube

47

Відповідь @ 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, але не для обробки мережі; вам потрібно його серіалізувати та передати на HttpURLC-з'єднання до POST.


JSONObject j = новий JSONObject (); j.put ("ім'я", "моє ім'я"); j.put ("вік", "20"); Щось схоже на те? Як я це серіалізую?
asdf007

@ asdf007 просто використовувати j.toString().
Алекс Черчілл

Це правда, це з'єднання блокується. Це, мабуть, не велика справа, якщо ви надсилаєте пошту; набагато важливіше, якщо ви запускаєте веб-сервер.
Алекс Черчілль

Посилання 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();
}

Дякую! Лише ваша відповідь вирішила питання кодування :)
Шрікант,

@SonuDhakar, чому ви надсилаєте application/jsonі як заголовок прийняття, і як тип вмісту
Kasun Siyambalapitiya

Здається, 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

Ви можете використовувати наступний код з HTTP Apache:

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 в String або 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-запит, побудований на апачі 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.