POST HTTP za pomocą JSON w Javie


188

Chciałbym wykonać prosty HTTP POST przy użyciu JSON w Javie.

Powiedzmy, że adres URL to www.site.com

i przyjmuje wartość {"name":"myname","age":"20"}oznaczoną jako 'details'na przykład.

Jak powinienem przejść do tworzenia składni dla testu POST?

Nie mogę również znaleźć metody POST w JSON Javadocs.

Odpowiedzi:


167

Oto, co musisz zrobić:

  1. Pobierz Apache HttpClient, umożliwi to złożenie wymaganego żądania
  2. Utwórz z nim żądanie HttpPost i dodaj nagłówek „application / x-www-form-urlencoded”
  3. Utwórz StringEntity, do którego przekażesz JSON
  4. Wykonaj połączenie

Kod z grubsza wygląda (nadal będziesz musiał go debugować i sprawić, by działał)

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

9
Możesz, ale zawsze dobrą praktyką jest wyodrębnianie go jako JSONObject, tak jakbyś robił bezpośrednio w ciągu, możesz źle zaprogramować ciąg i powodować błąd składniowy. Korzystając z JSONObject, upewniasz się, że twoja serializacja jest zawsze zgodna z odpowiednią strukturą JSON
— momo

3
Zasadniczo oboje tylko przesyłają dane. Jedyną różnicą jest to, jak przetwarzasz go na serwerze. Jeśli masz tylko kilka par klucz-wartość, to prawdopodobnie wystarczy zwykły parametr POST z klucz1 = wartość1, klucz2 = wartość2 itd., Ale gdy dane są bardziej złożone, a zwłaszcza zawierają złożoną strukturę (obiekt zagnieżdżony, tablice), chciałbyś zacznij rozważać użycie JSON. Wysyłanie złożonej struktury przy użyciu pary klucz-wartość byłoby bardzo nieprzyjemne i trudne do przeanalizowania na serwerze (możesz spróbować i zobaczysz to od razu). Wciąż pamiętam dzień, w którym musieliśmy to zrobić ... to nie było ładne ...
— momo

1
Miło, że mogłem pomóc! Jeśli tego właśnie szukasz, powinieneś zaakceptować odpowiedź, aby inni ludzie z podobnymi pytaniami mieli dobre odpowiedzi na ich pytania. Możesz użyć znacznika wyboru na odpowiedzi. Daj mi znać, jeśli masz dodatkowe pytania
— momo

12
Typ zawartości nie powinien być „application / json”. „application / x-www-form-urlencoded” oznacza, że ​​ciąg zostanie sformatowany podobnie jak ciąg zapytania. NM Widzę, co zrobiłeś, umieściłeś kroplę json jako wartość właściwości.
— Matthew Ward

1
Przestarzała część powinna zostać zastąpiona za pomocą CloseableHttpClient, co daje metodę .close (). Zobacz stackoverflow.com/a/20713689/1484047
— Frame91

92

Możesz skorzystać z biblioteki Gson, aby przekonwertować swoje klasy Java na obiekty JSON.

Utwórz klasę pojo dla zmiennych, które chcesz wysłać zgodnie z powyższym przykładem

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

staje się

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

po ustawieniu zmiennych w klasie pojo1 możesz wysłać to za pomocą następującego kodu

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

i to jest import

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;

i dla GSON

import com.google.gson.Gson;

1
cześć, jak tworzysz swój obiekt httpClient? Jest to interfejs
— 3290180

1
Tak, to jest interfejs. Możesz utworzyć instancję za pomocą „HttpClient httpClient = new DefaultHttpClient ();”
— Prakash

2
teraz jest to przestarzałe, musimy użyć HttpClient httpClient = HttpClientBuilder.create (). build ();
— user3290180

5
Jak importować HttpClientBuilder?
— Esterlink z

3
Uważam, że nieco prostsze jest użycie parametru ContentType w konstruktorze StringUtils i przekazanie ContentType.APPLICATION_JSON zamiast ręcznego ustawiania nagłówka.
— TownCube,

47

Odpowiedź @ momo dla Apache HttpClient, wersja 4.3.1 lub nowsza. Używam JSON-Javado budowy mojego obiektu 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();
}

20

Prawdopodobnie najłatwiej jest użyć HttpURLConnection .

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

Użyjesz JSONObject lub cokolwiek innego, aby zbudować JSON, ale nie do obsługi sieci; musisz go serializować, a następnie przekazać do połączenia HttpURLC POST.


JSONObject j = new JSONObject (); j.put („nazwa”, „moja nazwa”); j.put („wiek”, „20”); Tak? Jak mogę serializować?
— asdf007

@ asdf007 wystarczy użyć j.toString().
— Alex Churchill,

To prawda, to połączenie blokuje. To prawdopodobnie nie jest wielka sprawa, jeśli wysyłasz POST; jest to o wiele ważniejsze, jeśli prowadzisz serwer WWW.
— Alex Churchill,

Łącze HttpURLConnection nie działa.
— Tobias Roland,

czy możesz napisać przykład, jak wysłać JSON do treści?

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

7
Rozważ edycję swojego posta, aby dodać więcej wyjaśnień na temat tego, co robi Twój kod i dlaczego rozwiąże problem. Odpowiedź, która w większości zawiera tylko kod (nawet jeśli działa), zwykle nie pomaga OP zrozumieć ich problemu
— Reeno

14

Wypróbuj ten kod:

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

Dzięki! Tylko twoja odpowiedź rozwiązała problem z kodowaniem :)
— Shrikant

@SonuDhakar, dlaczego wysyłasz application/jsonzarówno jako nagłówek akceptacji, jak i typ zawartości
— Kasun Siyambalapitiya

Wygląda na DefaultHttpClientto, że jest przestarzałe.
— sdgfsdh

11

Znalazłem to pytanie, szukając rozwiązania, w jaki sposób wysłać żądanie postu od klienta Java do punktów końcowych Google. Powyższe odpowiedzi, prawdopodobnie poprawne, ale nie działają w przypadku punktów końcowych Google.

Rozwiązanie dla punktów końcowych Google.

  1. Treść żądania musi zawierać tylko ciąg JSON, a nie parę nazwa = wartość.
  2. Nagłówek typu treści musi być ustawiony na „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();
    }

    Z pewnością można to zrobić również za pomocą HttpClient.


8

Możesz użyć następującego kodu z Apache HTTP:

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

response = client.execute(request);

Dodatkowo możesz utworzyć obiekt Json i wstawić pola do obiektu w ten sposób

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

kluczową rzeczą jest dodanie ContentType.APPLICATION_JSON, w przeciwnym razie nie działałoby dla mnie nowe StringEntity (ładunek, ContentType.APPLICATION_JSON)
— Johnny Cage

2

W przypadku języka Java 11 możesz użyć nowego klienta 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();

Możesz użyć wydawcy z InputStream, String, File. Konwertując JSON na String lub IS, możesz dzięki Jacksonowi.


1

Java 8 z 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();
        }

0

Polecam żądanie http oparte na 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. 
}

Jeśli chcesz wysłać JSONjako treść żądania, możesz:

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

Zdecydowanie polecam przeczytać dokumentację przed użyciem.


dlaczego sugerujesz to w odpowiedzi na powyższą odpowiedź z największą popularnością?
— Jeryl Cook

Ponieważ jest bardzo prosty w użyciu i manipulować z reakcją.
— Beno Arakelyan
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.