HTTP POST utilisant JSON en Java

188

Je voudrais faire un HTTP POST simple en utilisant JSON en Java.

Disons que l'URL est www.site.com

et il prend la valeur {"name":"myname","age":"20"}étiquetée comme 'details'par exemple.

Comment créerais-je la syntaxe du POST?

Je n'arrive pas non plus à trouver une méthode POST dans les Javadocs JSON.

asdf007
la source

Réponses:

167

Voici ce que tu dois faire:

  1. Obtenez le Apache HttpClient, cela vous permettrait de faire la demande requise
  2. Créez une requête HttpPost avec elle et ajoutez l'en-tête "application / x-www-form-urlencoded"
  3. Créez une StringEntity que vous lui passerez JSON
  4. Exécuter l'appel

Le code ressemble à peu près (vous devrez toujours le déboguer et le faire fonctionner)

//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
la source
9
Vous pouvez mais c'est toujours une bonne pratique de l'abstraire comme JSONObject comme si vous le faisiez directement dans la chaîne, vous pourriez programmer la chaîne de manière incorrecte et provoquer une erreur de syntaxe. En utilisant JSONObject, vous vous assurez que votre sérialisation suit toujours la bonne structure JSON
momo
3
En principe, ils ne font que transmettre des données. La seule différence réside dans la manière dont vous le traitez sur le serveur. Si vous n'avez que quelques paires clé-valeur, un paramètre POST normal avec clé1 = valeur1, clé2 = valeur2, etc. est probablement suffisant, mais une fois que vos données sont plus complexes et contiennent en particulier une structure complexe (objet imbriqué, tableaux), vous voudrez commencez à envisager d'utiliser JSON. Envoyer une structure complexe à l'aide d'une paire clé-valeur serait très désagréable et difficile à analyser sur le serveur (vous pouvez essayer et vous le verrez tout de suite). Rappelez-vous encore le jour où nous avons dû faire ça urgh .. ce n'était pas joli ..
momo
1
Heureux de vous aider! Si c'est ce que vous recherchez, vous devez accepter la réponse afin que d'autres personnes ayant des questions similaires aient une bonne avance à leurs questions. Vous pouvez utiliser la coche sur la réponse. Faites-moi savoir si vous avez d'autres questions
momo
12
Le type de contenu ne devrait-il pas être «application / json». 'application / x-www-form-urlencoded' implique que la chaîne sera formatée de la même manière qu'une chaîne de requête. NM Je vois ce que vous avez fait, vous mettez le blob json comme valeur d'une propriété.
Matthew Ward
1
La partie obsolète doit être remplacée par l'utilisation de CloseableHttpClient qui vous donne une méthode .close (). Voir stackoverflow.com/a/20713689/1484047
Frame91
92

Vous pouvez utiliser la bibliothèque Gson pour convertir vos classes java en objets JSON.

Créez une classe pojo pour les variables que vous souhaitez envoyer selon l'exemple ci-dessus

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

devient

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

une fois que vous avez défini les variables dans la classe pojo1, vous pouvez envoyer cela en utilisant le code suivant

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

et ce sont les importations

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;

et pour GSON

import com.google.gson.Gson;
Prakash
la source
1
salut, comment créez-vous votre objet httpClient? C'est une interface
user3290180
1
Oui, c'est une interface. Vous pouvez créer une instance en utilisant 'HttpClient httpClient = new DefaultHttpClient ();'
Prakash le
2
maintenant que c'est obsolète, nous devons utiliser HttpClient httpClient = HttpClientBuilder.create (). build ();
user3290180
5
Comment importer HttpClientBuilder?
Esterlink du
3
Je trouve qu'il est légèrement plus propre d'utiliser le paramètre ContentType sur le constructeur StringUtils et de passer ContentType.APPLICATION_JSON au lieu de définir manuellement l'en-tête.
TownCube
48

Réponse de @ momo pour Apache HttpClient, version 4.3.1 ou ultérieure. J'utilise JSON-Javapour créer mon objet 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();
}
Leonel Sanches da Silva
la source
20

Il est probablement plus simple d'utiliser HttpURLConnection .

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

Vous utiliserez JSONObject ou autre pour construire votre JSON, mais pas pour gérer le réseau; vous devez le sérialiser, puis le transmettre à un HttpURLConnection à POST.

Alex Churchill
la source
JSONObject j = nouveau JSONObject (); j.put ("nom", "mon nom"); j.put ("âge", "20"); Comme ça? Comment le sérialiser?
asdf007
@ asdf007 utilisez simplement j.toString().
Alex Churchill
C'est vrai, cette connexion est bloquante. Ce n'est probablement pas un gros problème si vous envoyez un POST; c'est beaucoup plus important si vous exécutez un serveur Web.
Alex Churchill
Le lien HttpURLConnection est mort.
Tobias Roland
pouvez-vous poster un exemple comment poster json au corps?
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
la source
7
Veuillez envisager de modifier votre message pour ajouter plus d'explications sur ce que fait votre code et pourquoi il résoudra le problème. Une réponse qui contient principalement du code (même si cela fonctionne) n'aidera généralement pas l'OP à comprendre son problème
Reeno
14

Essayez ce 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
la source
Merci! Seule votre réponse a résolu le problème d'encodage :)
Shrikant
@SonuDhakar pourquoi vous envoyez à la application/jsonfois comme en-tête d'acceptation et comme type de contenu
Kasun Siyambalapitiya
Il semble que ce DefaultHttpClientsoit obsolète.
sdgfsdh
11

J'ai trouvé cette question à la recherche d'une solution sur la façon d'envoyer une demande de publication du client java à Google Endpoints. Au-dessus des réponses, très probablement correctes, mais ne fonctionnent pas dans le cas de Google Endpoints.

Solution pour Google Endpoints.

  1. Le corps de la requête doit contenir uniquement une chaîne JSON, pas une paire nom = valeur.
  2. L'en-tête du type de contenu doit être défini sur "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();
    }

    Cela peut certainement être fait en utilisant HttpClient.

yurin
la source
8

Vous pouvez utiliser le code suivant avec Apache HTTP:

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

response = client.execute(request);

De plus, vous pouvez créer un objet json et placer des champs dans l'objet comme ceci

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
la source
la chose clé est d'ajouter ContentType.APPLICATION_JSON sinon cela ne fonctionnait pas pour moi new StringEntity (payload, ContentType.APPLICATION_JSON)
Johnny Cage
2

Pour Java 11, vous pouvez utiliser un nouveau 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();

Vous pouvez utiliser l'éditeur de InputStream, String, File. Vous pouvez convertir JSON en String ou IS avec Jackson.

user3359592
la source
1

Java 8 avec 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
la source
0

Je recommande http-request construit sur 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. 
}

Si vous souhaitez envoyer JSONle corps de la demande, vous pouvez:

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

Je recommande vivement de lire la documentation avant utilisation.

Beno Arakelyan
la source
pourquoi suggérez-vous cela sur la réponse ci-dessus avec le plus de votes positifs?
Jeryl Cook le
Parce qu'il est très simple à utiliser et à manipuler avec réponse.
Beno Arakelyan