¿Cómo POSTAR una solicitud JSON usando Apache HttpClient?

91

Tengo algo como lo siguiente:

final String url = "http://example.com";

final HttpClient httpClient = new HttpClient();
final PostMethod postMethod = new PostMethod(url);
postMethod.addRequestHeader("Content-Type", "application/json");
postMethod.addParameters(new NameValuePair[]{
        new NameValuePair("name", "value)
});
httpClient.executeMethod(httpMethod);
postMethod.getResponseBodyAsStream();
postMethod.releaseConnection();

Sigue regresando con un 500. El proveedor de servicios dice que necesito enviar JSON. ¿Cómo se hace eso con Apache HttpClient 3.1+?

Noel Yap
fuente
2
Su NameValuePairsimplemente añade un parámetro de la petición, no se va a enviar cualquier JSON en el código. ¿Qué estructura JSON espera recibir el servicio, cuáles son sus datos para enviar? Está buscando postMethod.setRequestEntity()con un StringRequestEntityque contenga su JSON.
Philipp Reichart

Respuestas:

188

Apache HttpClient no sabe nada sobre JSON, por lo que deberá construir su JSON por separado. Para hacerlo, recomiendo consultar la biblioteca JSON-java simple de json.org . (Si "JSON-java" no le conviene, json.org tiene una gran lista de bibliotecas disponibles en diferentes idiomas).

Una vez que haya generado su JSON, puede usar algo como el siguiente código para PUBLICARLO

StringRequestEntity requestEntity = new StringRequestEntity(
    JSON_STRING,
    "application/json",
    "UTF-8");

PostMethod postMethod = new PostMethod("http://example.com/action");
postMethod.setRequestEntity(requestEntity);

int statusCode = httpClient.executeMethod(postMethod);

Editar

Nota: la respuesta anterior, como se solicita en la pregunta, se aplica a Apache HttpClient 3.1. Sin embargo, para ayudar a cualquiera que busque una implementación contra el último cliente de Apache:

StringEntity requestEntity = new StringEntity(
    JSON_STRING,
    ContentType.APPLICATION_JSON);

HttpPost postMethod = new HttpPost("http://example.com/action");
postMethod.setEntity(requestEntity);

HttpResponse rawResponse = httpclient.execute(postMethod);
janosido
fuente
¿Cómo se puede agregar json a geturl?
Mr Lou
1
¿Siempre quiso saber si parameterse puede agregar POSTMethody al mismo tiempo establecer un RequestEntity? Sé que suena ilógico, pero solo curioso.
pregunta
33
Para aquellos que se preguntan, StringRequestEntityha sido reemplazado por StringEntity.
Alex
9
Con versiones posteriores de HttpClient, PostMethod había sido reemplazado por HttpPost.
Aviro
1
json enlace de referencia está roto
Simon K.
19

Para Apache HttpClient 4.5 o una versión más reciente:

    CloseableHttpClient httpclient = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://targethost/login");
    String JSON_STRING="";
    HttpEntity stringEntity = new StringEntity(JSON_STRING,ContentType.APPLICATION_JSON);
    httpPost.setEntity(stringEntity);
    CloseableHttpResponse response2 = httpclient.execute(httpPost);

Nota:

1 para compilar el código, se deben importar tanto el httpclientpaquete como el httpcorepaquete.

2 se ha omitido el bloque try-catch.

Referencia : guía oficial appache

el proyecto Commons HttpClient está ahora al final de su vida útil y ya no se está desarrollando. Ha sido reemplazado por el proyecto Apache HttpComponents en sus módulos HttpClient y HttpCore

ZhaoGang
fuente
3

Como se menciona en la excelente respuesta de janoside , debe construir la cadena JSON y configurarla como StringEntity.

Para construir la cadena JSON, puede usar cualquier biblioteca o método con el que se sienta cómodo. La biblioteca Jackson es un ejemplo sencillo:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;

ObjectMapper mapper = new ObjectMapper();
ObjectNode node = mapper.createObjectNode();
node.put("name", "value"); // repeat as needed
String JSON_STRING = node.toString();
postMethod.setEntity(new StringEntity(JSON_STRING, ContentType.APPLICATION_JSON));
ADTC
fuente