HTTP POST mit JSON in Java

186

Ich möchte einen einfachen HTTP-POST mit JSON in Java erstellen.

Angenommen, die URL lautet www.site.com

und es nimmt den {"name":"myname","age":"20"}wie 'details'zum Beispiel gekennzeichneten Wert an .

Wie würde ich die Syntax für den POST erstellen?

Ich kann auch keine POST-Methode in den JSON-Javadocs finden.

asdf007
quelle

Antworten:

167

Folgendes müssen Sie tun:

  1. Holen Sie sich den Apache HttpClient, damit Sie die erforderliche Anfrage stellen können
  2. Erstellen Sie damit eine HttpPost-Anfrage und fügen Sie den Header "application / x-www-form-urlencoded" hinzu.
  3. Erstellen Sie eine StringEntity, an die Sie JSON übergeben
  4. Führen Sie den Anruf aus

Der Code sieht ungefähr so ​​aus (Sie müssen ihn noch debuggen und zum Laufen bringen).

//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
quelle
9
Sie könnten es aber immer empfehlen, es als JSONObject zu abstrahieren, als ob Sie direkt in der Zeichenfolge arbeiten. Sie könnten die Zeichenfolge falsch programmieren und Syntaxfehler verursachen. Durch die Verwendung von JSONObject stellen Sie sicher, dass Ihre Serialisierung immer der richtigen JSON-Struktur folgt
momo
3
Im Prinzip übertragen beide nur Daten. Der einzige Unterschied besteht darin, wie Sie es auf dem Server verarbeiten. Wenn Sie nur wenige Schlüssel-Wert-Paare haben, reicht wahrscheinlich ein normaler POST-Parameter mit Schlüssel1 = Wert1, Schlüssel2 = Wert2 usw. aus. Wenn Ihre Daten jedoch komplexer sind und insbesondere eine komplexe Struktur (verschachteltes Objekt, Arrays) enthalten, möchten Sie dies Erwägen Sie die Verwendung von JSON. Das Senden einer komplexen Struktur mithilfe eines Schlüssel-Wert-Paares wäre sehr unangenehm und auf dem Server schwer zu analysieren (Sie könnten es versuchen und Sie werden es sofort sehen). Erinnern Sie sich noch an den Tag, an dem wir das dringend tun mussten. Es war nicht schön.
Momo
1
Froh, dass ich Helfen kann! Wenn Sie danach suchen, sollten Sie die Antwort akzeptieren, damit andere Personen mit ähnlichen Fragen gut zu ihren Fragen führen können. Sie können das Häkchen auf der Antwort verwenden. Lassen Sie mich wissen, wenn Sie weitere Fragen haben
Momo
12
Sollte der Inhaltstyp nicht "application / json" sein? 'application / x-www-form-urlencoded' impliziert, dass die Zeichenfolge ähnlich einer Abfragezeichenfolge formatiert wird. NM Ich verstehe, was Sie getan haben. Sie haben den JSON-Blob als Wert einer Eigenschaft angegeben.
Matthew Ward
1
Der veraltete Teil sollte durch die Verwendung von CloseableHttpClient ersetzt werden, wodurch Sie eine .close () - Methode erhalten. Siehe stackoverflow.com/a/20713689/1484047
Frame91
90

Sie können die Gson-Bibliothek verwenden, um Ihre Java-Klassen in JSON-Objekte zu konvertieren.

Erstellen Sie eine Pojo-Klasse für Variablen, die Sie wie im obigen Beispiel senden möchten

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

wird

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

Sobald Sie die Variablen in der Klasse pojo1 festgelegt haben, können Sie diese mit dem folgenden Code senden

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

und das sind die Importe

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;

und für GSON

import com.google.gson.Gson;
Prakash
quelle
1
Hallo, wie erstellen Sie Ihr httpClient-Objekt? Es ist eine Schnittstelle
user3290180
1
Ja das ist eine Schnittstelle. Sie können eine Instanz mit 'HttpClient httpClient = new DefaultHttpClient ();' erstellen.
Prakash
2
Jetzt, da es veraltet ist, müssen wir HttpClient verwenden. httpClient = HttpClientBuilder.create (). build ();
user3290180
5
Wie importiere ich HttpClientBuilder?
Esterlinkof
3
Ich finde es etwas sauberer, den ContentType-Parameter im StringUtils-Konstruktor zu verwenden und ContentType.APPLICATION_JSON zu übergeben, anstatt den Header manuell festzulegen.
TownCube
47

@ momos Antwort für Apache HttpClient, Version 4.3.1 oder höher. Ich verwende JSON-Javazum Erstellen meines JSON-Objekts:

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
quelle
20

Es ist wahrscheinlich am einfachsten, HttpURLConnection zu verwenden .

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

Sie verwenden JSONObject oder was auch immer, um Ihren JSON zu erstellen, aber nicht, um das Netzwerk zu verwalten. Sie müssen es serialisieren und dann an eine HttpURLConnection an POST übergeben.

Alex Churchill
quelle
JSONObject j = neues JSONObject (); j.put ("name", "myname"); j.put ("Alter", "20"); So wie das? Wie serialisiere ich es?
asdf007
@ asdf007 einfach benutzen j.toString().
Alex Churchill
Das stimmt, diese Verbindung blockiert. Dies ist wahrscheinlich keine große Sache, wenn Sie einen POST senden. Es ist viel wichtiger, wenn Sie einen Webserver ausführen.
Alex Churchill
Der HttpURLConnection-Link ist tot.
Tobias Roland
Kannst du ein Beispiel posten, wie man json auf body postet?
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();
}
Medo
quelle
7
Bitte überlegen Sie, Ihren Beitrag zu bearbeiten, um weitere Erklärungen dazu hinzuzufügen, was Ihr Code tut und warum er das Problem löst. Eine Antwort, die meistens nur Code enthält (auch wenn sie funktioniert), hilft dem OP normalerweise nicht, ihr Problem zu verstehen
Reeno
14

Versuchen Sie diesen Code:

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
quelle
Vielen Dank! Nur Ihre Antwort hat das Codierungsproblem gelöst :)
Shrikant
@ SonuDhakar, warum Sie application/jsonsowohl als Akzeptanz-Header als auch als Inhaltstyp senden
Kasun Siyambalapitiya
Es scheint, dass dies DefaultHttpClientveraltet ist.
SDGFSDH
11

Ich fand diese Frage auf der Suche nach einer Lösung zum Senden einer Post-Anfrage vom Java-Client an Google Endpoints. Die obigen Antworten sind sehr wahrscheinlich korrekt, funktionieren jedoch bei Google Endpoints nicht.

Lösung für Google Endpoints.

  1. Der Anforderungshauptteil darf nur eine JSON-Zeichenfolge enthalten, kein Name = Wert-Paar.
  2. Der Inhaltstyp-Header muss auf "application / json" gesetzt sein.

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

    Dies kann sicher auch mit HttpClient erfolgen.

Yurin
quelle
8

Sie können den folgenden Code mit Apache HTTP verwenden:

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

response = client.execute(request);

Außerdem können Sie ein JSON-Objekt erstellen und Felder wie folgt in das Objekt einfügen

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
quelle
Das Wichtigste ist, ContentType.APPLICATION_JSON hinzuzufügen, sonst funktionierte es für mich nicht. Neue StringEntity (Nutzdaten, ContentType.APPLICATION_JSON)
Johnny Cage
2

Für Java 11 können Sie einen neuen HTTP-Client verwenden :

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

Sie können Publisher aus InputStream, String, File verwenden. Konvertieren Sie JSON in den String oder IS, den Sie mit Jackson können.

user3359592
quelle
1

Java 8 mit 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();
        }
Duschan
quelle
0

Ich empfehle http-Anfrage auf Apache http API gebaut.

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. 
}

Wenn Sie als Anfragetext senden möchten, JSONkönnen Sie:

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

Ich empfehle dringend, die Dokumentation vor dem Gebrauch zu lesen.

Beno Arakelyan
quelle
Warum schlagen Sie dies über die obige Antwort mit den meisten positiven Stimmen vor?
Jeryl Cook
Weil es sehr einfach ist, mit Reaktion zu manipulieren.
Beno Arakelyan