Como fazer uma solicitação POST JSON usando Apache HttpClient?

89

Eu tenho algo como o seguinte:

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

Ele continua voltando com um 500. O provedor de serviços diz que preciso enviar JSON. Como isso é feito com o Apache HttpClient 3.1+?

Noel Yap
fonte
2
Você NameValuePairapenas adiciona um parâmetro de solicitação, você não está enviando nenhum JSON em seu código. Qual estrutura JSON o serviço espera receber, quais são os seus dados para enviar? Você está procurando postMethod.setRequestEntity()com um StringRequestEntityque contém seu JSON.
Philipp Reichart de

Respostas:

182

O Apache HttpClient não sabe nada sobre JSON, portanto, você precisará construir seu JSON separadamente. Para fazer isso, recomendo verificar a biblioteca JSON-java simples de json.org . (Se "JSON-java" não combina com você, json.org tem uma grande lista de bibliotecas disponíveis em diferentes idiomas.)

Depois de gerar seu JSON, você pode usar algo como o código abaixo para fazer um POST

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

Observação - A resposta acima, conforme solicitado na pergunta, se aplica ao Apache HttpClient 3.1. No entanto, para ajudar qualquer um que esteja procurando uma implementação no cliente Apache mais recente:

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);
janosida
fonte
Como posso anexar o json ao geturl?
Sr. Lou
1
Sempre quis saber se um parameterpode ser adicionado POSTMethode ao mesmo tempo definir um RequestEntitya ele? Eu sei que parece ilógico, mas apenas curioso.
asgs de
31
Para quem está se perguntando, StringRequestEntityfoi substituído por StringEntity.
Alex
8
Com versões posteriores do HttpClient, PostMethod foi substituído pelo HttpPost.
Aviro,
1
O link de referência da json está quebrado
Simon K.
15

Para Apache HttpClient 4.5 ou versão mais recente:

    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 fazer a compilação do código, o httpclientpacote e o httpcorepacote devem ser importados.

2 blocos try-catch foram omitidos.

Referência : guia oficial do appache

o projeto Commons HttpClient chegou ao fim da vida útil e não está mais sendo desenvolvido. Ele foi substituído pelo projeto Apache HttpComponents em seus módulos HttpClient e HttpCore

ZhaoGang
fonte
2

Conforme mencionado na excelente resposta de janoside , você precisa construir a string JSON e defini-la como um StringEntity.

Para construir a string JSON, você pode usar qualquer biblioteca ou método com o qual se sinta confortável. A biblioteca Jackson é um exemplo fácil:

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
fonte