POST HTTP che utilizza JSON in Java


188

Vorrei creare un semplice POST HTTP utilizzando JSON in Java.

Diciamo che l'URL è www.site.com

e accetta il valore {"name":"myname","age":"20"}etichettato come 'details'per esempio.

Come farei per creare la sintassi per il POST?

Inoltre, non riesco a trovare un metodo POST nel JSON Javadocs.

Risposte:


167

Ecco cosa devi fare:

  1. Ottieni Apache HttpClient, questo ti consentirebbe di effettuare la richiesta richiesta
  2. Crea una richiesta HttpPost con essa e aggiungi l'intestazione "application / x-www-form-urlencoded"
  3. Crea un StringEntity che gli passerai JSON
  4. Eseguire la chiamata

Il codice appare approssimativamente (dovrai ancora eseguire il debug e farlo funzionare)

//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
Potresti, ma è sempre buona pratica astrarre come JSONObject come se stessi facendo direttamente nella stringa, potresti programmare la stringa in modo errato e causare errori di sintassi. Usando JSONObject ti assicuri che la tua serializzazione segua sempre la giusta struttura JSON
momo

3
In linea di principio, entrambi stanno semplicemente trasmettendo dati. L'unica differenza è la modalità di elaborazione nel server. Se hai solo poche coppie chiave-valore, probabilmente è sufficiente un normale parametro POST con key1 = value1, key2 = value2, ecc., Ma una volta che i tuoi dati sono più complessi e soprattutto contenenti una struttura complessa (oggetto nidificato, array), vorrai iniziare a considerare l'utilizzo di JSON. Inviare una struttura complessa usando una coppia chiave-valore sarebbe molto sgradevole e difficile da analizzare sul server (potresti provare e lo vedrai subito). Ricordo ancora il giorno in cui dovevamo fare quell'urgh .. non era carino ..
momo

1
Felice di aiutare! Se questo è ciò che stai cercando, dovresti accettare la risposta in modo che altre persone con domande simili abbiano buone risposte alle loro domande. È possibile utilizzare il segno di spunta sulla risposta. Fammi sapere se hai ulteriori domande
momo

12
Il tipo di contenuto non dovrebbe essere 'application / json'. 'application / x-www-form-urlencoded' implica che la stringa verrà formattata in modo simile a una stringa di query. NM Vedo cosa hai fatto, hai messo il BLOB JSON come valore di una proprietà.
Matthew Ward,

1
La parte obsoleta deve essere sostituita utilizzando CloseableHttpClient che fornisce un metodo .close (). Vedere stackoverflow.com/a/20713689/1484047
Frame91

92

È possibile utilizzare la libreria Gson per convertire le classi java in oggetti JSON.

Crea una classe pojo per le variabili che vuoi inviare come sopra Esempio

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

diventa

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

una volta impostate le variabili nella classe pojo1, puoi inviarle usando il seguente codice

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

e queste sono le importazioni

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;

e per GSON

import com.google.gson.Gson;

1
ciao, come si crea l'oggetto httpClient? È un'interfaccia
user3290180,

1
Sì, questa è un'interfaccia. Puoi creare un'istanza usando 'HttpClient httpClient = new DefaultHttpClient ();'
Prakash,

2
ora che è deprecato, dobbiamo usare HttpClient httpClient = HttpClientBuilder.create (). build ();
user3290180,

5
Come importare HttpClientBuilder?
Esterlink del

3
Trovo leggermente più pulito usare il parametro ContentType sul costruttore StringUtils e passare ContentType.APPLICATION_JSON invece di impostare manualmente l'intestazione.
TownCube,

48

La risposta di @ momo per Apache HttpClient, versione 4.3.1 o successive. Sto usando JSON-Javaper costruire il mio oggetto 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

Probabilmente è più facile usare HttpURLConnection .

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

Utilizzerai JSONObject o qualsiasi altra cosa per costruire il tuo JSON, ma non per gestire la rete; è necessario serializzarlo e quindi passarlo a una connessione HttpURLC a POST.


JSONObject j = new JSONObject (); j.put ("name", "myname"); j.put ("age", "20"); Come quello? Come lo serializzo?
asdf007,

@ asdf007 basta usare j.toString().
Alex Churchill,

È vero, questa connessione sta bloccando. Questo probabilmente non è un grosso problema se stai inviando un POST; è molto più importante se si esegue un server web.
Alex Churchill

Il collegamento HttpURLConnection è morto.
Tobias Roland,

puoi pubblicare un esempio su come pubblicare json in body?

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
Ti consigliamo di modificare il tuo post per aggiungere ulteriori spiegazioni su cosa fa il tuo codice e perché risolverà il problema. Una risposta che per lo più contiene solo codice (anche se funziona) di solito non aiuterà l'OP a capire il loro problema
Reeno,

14

Prova questo codice:

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

Grazie! Solo la tua risposta ha risolto il problema della codifica :)
Shrikant,

@SonuDhakar perché invii application/jsonsia come intestazione accetta sia come tipo di contenuto
Kasun Siyambalapitiya

Sembra che DefaultHttpClientsia deprecato.
sdgfsdh,

11

Ho trovato questa domanda in cerca di una soluzione su come inviare la richiesta di post dal client Java agli endpoint di Google. Risposte sopra, molto probabilmente corrette, ma non funzionano in caso di endpoint Google.

Soluzione per gli endpoint di Google.

  1. Il corpo della richiesta deve contenere solo una stringa JSON, non una coppia nome = valore.
  2. L'intestazione del tipo di contenuto deve essere impostata su "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();
    }

    Di sicuro può essere fatto anche usando HttpClient.


8

Puoi usare il seguente codice con Apache HTTP:

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

response = client.execute(request);

Inoltre puoi creare un oggetto json e inserire i campi nell'oggetto in questo modo

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

la cosa fondamentale è aggiungere ContentType.APPLICATION_JSON altrimenti non funzionava per me nuovo StringEntity (payload, ContentType.APPLICATION_JSON)
Johnny Cage,

2

Per Java 11 è possibile utilizzare il nuovo client 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();

Puoi utilizzare l'editore da InputStream, String, File. Convertire Jackson in String o IS è possibile con Jackson.


1

Java 8 con 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

Consiglio vivamente la richiesta http basata su 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. 
}

Se si desidera inviare JSONcome corpo della richiesta è possibile:

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

Consiglio vivamente di leggere la documentazione prima dell'uso.


perché lo consigli sulla risposta sopra con il maggior numero di voti?
Jeryl Cook,

Perché è molto semplice da usare e manipolare con risposta.
Beno Arakelyan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.