POST HTTP usando JSON en Java

188

Me gustaría hacer una POST HTTP simple usando JSON en Java.

Digamos que la URL es www.site.com

y toma el valor {"name":"myname","age":"20"}etiquetado como 'details'por ejemplo.

¿Cómo haría para crear la sintaxis para la POST?

Tampoco parece que pueda encontrar un método POST en JSON Javadocs.

asdf007
fuente

Respuestas:

167

Aquí está lo que tú necesitas hacer:

  1. Obtenga el HttpClient de Apache, esto le permitiría realizar la solicitud requerida
  2. Cree una solicitud HttpPost con ella y agregue el encabezado "application / x-www-form-urlencoded"
  3. Cree una StringEntity que le pasará JSON
  4. Ejecutar la llamada

El código se ve más o menos así (aún tendrá que depurarlo y hacerlo funcionar)

//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
fuente
9
Podría, pero siempre es una buena práctica resumirlo como JSONObject, como si lo estuviera haciendo directamente en la cadena, podría programar la cadena incorrectamente y causar un error de sintaxis. Al usar JSONObject, se asegura de que su serialización siempre siga la estructura JSON correcta
momo
3
En principio, ambos solo están transmitiendo datos. La única diferencia es cómo lo procesas en el servidor. Si solo tiene unos pocos pares clave-valor, un parámetro POST normal con clave1 = valor1, clave2 = valor2, etc. probablemente sea suficiente, pero una vez que sus datos sean más complejos y contengan especialmente estructuras complejas (objetos anidados, matrices), deseará comience a considerar el uso de JSON. Enviar una estructura compleja utilizando un par clave-valor sería muy desagradable y difícil de analizar en el servidor (puede intentarlo y lo verá de inmediato). Todavía recuerdo el día en que tuvimos que hacer eso urgh .. no fue bonito ..
momo
1
¡Encantado de ayudar! Si esto es lo que está buscando, debe aceptar la respuesta para que otras personas con preguntas similares tengan una buena respuesta a sus preguntas. Puede usar la marca de verificación en la respuesta. Avíseme si tiene más preguntas
momo
12
¿No debería ser el tipo de contenido 'application / json'? 'application / x-www-form-urlencoded' implica que la cadena tendrá un formato similar a una cadena de consulta. NM Veo lo que hiciste, pones la json blob como valor de una propiedad.
Matthew Ward,
1
La parte en desuso debe reemplazarse utilizando CloseableHttpClient que le proporciona un método .close (). Ver stackoverflow.com/a/20713689/1484047
Frame91
92

Puede utilizar la biblioteca Gson para convertir sus clases de Java en objetos JSON.

Cree una clase pojo para las variables que desea enviar según el ejemplo anterior

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

se convierte

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

una vez que establezca las variables en la clase pojo1, puede enviarlas usando el siguiente código

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

y estas son las importaciones

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;

y para GSON

import com.google.gson.Gson;
Prakash
fuente
1
hola, ¿cómo creas tu objeto httpClient? Es una interfaz
user3290180
1
Sí, eso es una interfaz. Puede crear una instancia usando 'HttpClient httpClient = new DefaultHttpClient ();'
Prakash
2
ahora que está en desuso, debemos usar HttpClient httpClient = HttpClientBuilder.create (). build ();
user3290180
55
¿Cómo importar HttpClientBuilder?
Esterlinkof
3
Me parece un poco más limpio usar el parámetro ContentType en el constructor StringUtils y pasar ContentType.APPLICATION_JSON en lugar de configurar manualmente el encabezado.
TownCube
48

La respuesta de @momo para Apache HttpClient, versión 4.3.1 o posterior. Estoy usando JSON-Javapara construir mi objeto 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
fuente
20

Probablemente sea más fácil usar HttpURLConnection .

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

Utilizará JSONObject o lo que sea para construir su JSON, pero no para manejar la red; necesita serializarlo y luego pasarlo a una conexión HttpURLConnection a POST.

Alex Churchill
fuente
JSONObject j = nuevo JSONObject (); j.put ("nombre", "mi nombre"); j.put ("edad", "20"); ¿Como eso? ¿Cómo lo serializo?
asdf007
@ asdf007 solo use j.toString().
Alex Churchill
Eso es cierto, esta conexión está bloqueando. Esto probablemente no sea un gran problema si está enviando una POST; Es mucho más importante si ejecuta un servidor web.
Alex Churchill
El enlace HttpURLConnection está muerto.
Tobias Roland
¿Puedes publicar un ejemplo de cómo publicar json en el cuerpo?
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
fuente
77
Considere editar su publicación para agregar más explicaciones sobre lo que hace su código y por qué resolverá el problema. Una respuesta que en su mayoría solo contiene código (incluso si está funcionando) generalmente no ayudará al OP a comprender su problema
Reeno
14

Prueba este código:

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
fuente
¡Gracias! Solo su respuesta resolvió el problema de codificación :)
Shrikant
@SonuDhakar por qué envía application/jsontanto como encabezado de aceptación como tipo de contenido
Kasun Siyambalapitiya
Parece que DefaultHttpClientestá en desuso.
sdgfsdh
11

Encontré esta pregunta buscando una solución sobre cómo enviar una solicitud de publicación desde el cliente de Java a Google Endpoints. Las respuestas anteriores, muy probablemente correctas, pero no funcionan en el caso de Google Endpoints.

Solución para puntos finales de Google.

  1. El cuerpo de la solicitud debe contener solo una cadena JSON, no un par nombre = valor.
  2. El encabezado de tipo de contenido debe establecerse en "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();
    }

    Seguro que también se puede hacer usando HttpClient.

yurin
fuente
8

Puede usar el siguiente código con Apache HTTP:

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

response = client.execute(request);

Además, puede crear un objeto json y poner campos en el objeto como este

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
fuente
Lo clave es agregar ContentType.APPLICATION_JSON; de lo contrario, no funcionaba para mí new StringEntity (payload, ContentType.APPLICATION_JSON)
Johnny Cage
2

Para Java 11 puede usar un nuevo cliente 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();

Puede usar el editor desde InputStream, String, File. Convierte JSON a String o IS con Jackson.

usuario3359592
fuente
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();
        }
Dushan
fuente
0

Recomiendo http-request basado en 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 desea enviar JSONcomo cuerpo de solicitud puede:

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

Recomiendo leer la documentación antes de usar.

Beno Arakelyan
fuente
¿Por qué sugieres esto sobre la respuesta anterior con la mayoría de los votos?
Jeryl Cook
Porque es muy simple de usar y manipular con respuesta.
Beno Arakelyan