Jak POST wysłać żądanie JSON za pomocą Apache HttpClient?

91

Mam coś takiego:

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

Wraca z 500. Usługodawca mówi, że muszę wysłać JSON. Jak to się robi z Apache HttpClient 3.1+?

Noel Yap
źródło
2
Po NameValuePairprostu dodajesz parametr żądania, nie wysyłasz żadnego JSON w swoim kodzie. Jaką strukturę JSON oczekuje usługa, jakie dane ma przesłać? Szukasz postMethod.setRequestEntity()z StringRequestEntityplikiem zawierającym JSON.
Philipp Reichart,

Odpowiedzi:

188

Apache HttpClient nie wie nic o JSON, więc musisz osobno skonstruować JSON. Aby to zrobić, polecam sprawdzić prostą bibliotekę JSON-java z json.org . (Jeśli „JSON-java” Ci nie odpowiada, w serwisie json.org znajduje się duża lista bibliotek dostępnych w różnych językach).

Po wygenerowaniu JSON możesz użyć czegoś takiego jak poniższy kod, aby go 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);

Edytować

Uwaga - powyższa odpowiedź, zgodnie z pytaniem, dotyczy Apache HttpClient 3.1. Jednak, aby pomóc każdemu, kto szuka implementacji dla najnowszego klienta 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);
janozyd
źródło
Jak dołączyć json do geturl?
Pan Lou,
1
Zawsze chciałeś wiedzieć, czy parametermożna do niego dodać POSTMethodi jednocześnie ustawić a RequestEntity? Wiem, że to brzmi nielogicznie, ale po prostu ciekawie.
asgs
33
Dla zastanawiających StringRequestEntityzostał zastąpiony przez StringEntity.
Alex
9
W późniejszych wersjach HttpClient PostMethod został zastąpiony przez HttpPost.
Aviro
1
json odsyłacz jest uszkodzony
Simon K.
19

Dla Apache HttpClient 4.5 lub nowszej wersji:

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

Uwaga:

1 w celu skompilowania kodu należy zaimportować zarówno httpclientpakiet , jak i httpcorepakiet.

2 blok try-catch został pominięty.

Referencje : appache oficjalny przewodnik

projekt Commons HttpClient dobiegł końca i nie jest już rozwijany. Został zastąpiony projektem Apache HttpComponents w jego modułach HttpClient i HttpCore

ZhaoGang
źródło
3

Jak wspomniano w doskonałej odpowiedzi janoside , musisz skonstruować ciąg JSON i ustawić go jako plik StringEntity.

Aby skonstruować ciąg JSON, możesz użyć dowolnej biblioteki lub metody, z którą czujesz się komfortowo. Biblioteka Jacksona to prosty przykład:

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
źródło