HTTP POST menggunakan JSON di Java

188

Saya ingin membuat POST HTTP sederhana menggunakan JSON di Jawa.

Katakanlah URL itu www.site.com

dan itu mengambil nilai yang {"name":"myname","age":"20"}berlabel sebagai 'details'contoh.

Bagaimana cara saya membuat sintaks untuk POST?

Saya juga sepertinya tidak bisa menemukan metode POST di JSON Javadocs.

asdf007
sumber

Jawaban:

167

Inilah yang perlu Anda lakukan:

  1. Dapatkan Apache HttpClient, ini akan memungkinkan Anda untuk membuat permintaan yang diperlukan
  2. Buat permintaan HttpPost dengannya dan tambahkan tajuk "application / x-www-form-urlencoded"
  3. Buat StringEntity yang akan Anda berikan JSON untuk itu
  4. Jalankan panggilan

Sepertinya kode itu kira-kira (Anda masih perlu melakukan debug dan membuatnya berfungsi)

//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(); 
}
momo
sumber
9
Anda bisa tetapi selalu praktik yang baik untuk abstrak itu sebagai JSONObject seolah-olah Anda melakukan secara langsung dalam string, Anda mungkin memprogram string salah dan menyebabkan kesalahan sintaksis. Dengan menggunakan JSONObject, Anda memastikan bahwa serialisasi Anda selalu mengikuti struktur JSON yang tepat
momo
3
Pada prinsipnya, keduanya hanya mengirimkan data. Satu-satunya perbedaan adalah bagaimana Anda memprosesnya di server. Jika Anda hanya memiliki beberapa pasangan nilai kunci maka parameter POST normal dengan key1 = value1, key2 = value2, dll mungkin sudah cukup, tetapi sekali data Anda lebih kompleks dan terutama mengandung struktur kompleks (objek bersarang, array) Anda ingin mulai pertimbangkan menggunakan JSON. Mengirim struktur kompleks menggunakan pasangan kunci-nilai akan sangat buruk dan sulit untuk diurai di server (Anda bisa mencoba dan Anda akan segera melihatnya). Masih ingat hari ketika kami harus melakukan itu urgh .. itu tidak cantik ..
momo
1
Senang untuk membantu! Jika ini yang Anda cari, Anda harus menerima jawabannya sehingga orang lain dengan pertanyaan yang sama memiliki petunjuk yang baik untuk pertanyaan mereka. Anda dapat menggunakan tanda centang pada jawabannya. Beritahu saya jika Anda memiliki pertanyaan lebih lanjut
momo
12
Bukankah tipe kontennya adalah 'aplikasi / json'. 'application / x-www-form-urlencoded' menyiratkan string akan diformat mirip dengan string kueri. NM Saya melihat apa yang Anda lakukan, Anda menempatkan json blob sebagai nilai properti.
Matthew Ward
1
Bagian yang sudah usang harus diganti dengan menggunakan CloseableHttpClient yang memberi Anda metode .close () -. Lihat stackoverflow.com/a/20713689/1484047
Frame91
92

Anda dapat menggunakan pustaka Gson untuk mengonversi kelas java Anda menjadi objek JSON.

Buat kelas pojo untuk variabel yang ingin Anda kirim sesuai Contoh di atas

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

menjadi

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

setelah Anda mengatur variabel di kelas pojo1 Anda dapat mengirimnya menggunakan kode berikut

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);

dan ini adalah impor

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;

dan untuk GSON

import com.google.gson.Gson;
Prakash
sumber
1
hai, bagaimana Anda membuat objek httpClient Anda? Ini adalah antarmuka
user3290180
1
Ya itu Antarmuka. Anda dapat membuat instance menggunakan 'HttpClient httpClient = new DefaultHttpClient ();'
Prakash
2
sekarang sudah tidak digunakan lagi, kita harus menggunakan HttpClient httpClient = HttpClientBuilder.create (). build ();
user3290180
5
Bagaimana cara mengimpor HttpClientBuilder?
Esterlinkof
3
Saya merasa sedikit lebih bersih untuk menggunakan parameter ContentType pada konstruktor StringUtils dan meneruskan ContentType.APPLICATION_JSON daripada mengatur header secara manual.
TownCube
47

@ momo menjawab untuk Apache HttpClient, versi 4.3.1 atau yang lebih baru. Saya menggunakan JSON-Javauntuk membangun objek JSON saya:

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();
}
Leonel Sanches da Silva
sumber
20

Mungkin paling mudah menggunakan HttpURLConnection .

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

Anda akan menggunakan JSONObject atau apa pun untuk membangun JSON Anda, tetapi tidak untuk menangani jaringan; Anda perlu membuat cerita bersambung dan kemudian meneruskannya ke HttpURLConnection ke POST.

Alex Churchill
sumber
JSONObject j = JSONObject baru (); j.put ("name", "myname"); j.put ("umur", "20"); Seperti itu? Bagaimana cara saya membuat serial?
asdf007
@ asdf007 cukup gunakan j.toString().
Alex Churchill
Itu benar, koneksi ini sedang memblokir. Ini mungkin bukan masalah besar jika Anda mengirim POST; itu jauh lebih penting jika Anda menjalankan server web.
Alex Churchill
Tautan HttpURLConnection sudah mati.
Tobias Roland
dapatkah Anda memposting contoh cara memposting json ke badan?
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();
}
Sedang
sumber
7
Silakan pertimbangkan untuk mengedit posting Anda untuk menambahkan lebih banyak penjelasan tentang apa kode Anda dan mengapa itu akan menyelesaikan masalah. Sebuah jawaban yang sebagian besar hanya berisi kode (bahkan jika itu berfungsi) biasanya tidak akan membantu OP untuk memahami masalah mereka
Reeno
14

Coba kode ini:

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();
}
Sonu Dhakar
sumber
Terima kasih! Hanya jawaban Anda yang memecahkan masalah penyandian :)
Shrikant
@SonuDhakar mengapa Anda mengirim application/jsonkeduanya sebagai tajuk terima dan sebagai tipe konten
Kasun Siyambalapitiya
Tampaknya DefaultHttpClientsudah usang.
sdgfsdh
11

Saya menemukan pertanyaan ini mencari solusi tentang cara mengirim permintaan pos dari klien java ke Google Endpoints. Jawaban di atas, sangat mungkin benar, tetapi tidak berfungsi jika ada Google Endpoints.

Solusi untuk Google Endpoints.

  1. Badan permintaan harus hanya berisi string JSON, bukan pasangan nama = nilai.
  2. Header tipe konten harus diatur ke "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();
    }

    Itu pasti bisa dilakukan dengan menggunakan HttpClient juga.

yurin
sumber
8

Anda dapat menggunakan kode berikut dengan Apache HTTP:

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

response = client.execute(request);

Selain itu Anda dapat membuat objek json dan memasukkan bidang ke objek seperti ini

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));
TMO
sumber
kuncinya adalah menambahkan ContentType.APPLICATION_JSON jika tidak itu tidak berfungsi untuk saya StringEntity baru (payload, ContentType.APPLICATION_JSON)
Johnny Cage
2

Untuk Java 11 Anda dapat menggunakan klien HTTP baru :

 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();

Anda dapat menggunakan penerbit dari InputStream, String, File. Konversi JSON ke String atau IS Anda bisa dengan Jackson.

pengguna3359592
sumber
1

Java 8 dengan 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();
        }
Dushan
sumber
0

Saya merekomendasikan http-request yang dibangun di atas 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. 
}

Jika Anda ingin mengirim JSONsebagai badan permintaan, Anda dapat:

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

Saya sangat merekomendasikan membaca dokumentasi sebelum digunakan.

Beno Arakelyan
sumber
mengapa Anda menyarankan ini di atas jawaban dengan sebagian besar upvotes?
Jeryl Cook
Karena sangat mudah digunakan dan melakukan manipulasi dengan respons.
Beno Arakelyan