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.

asdf007
źródło

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(); 
}
momo
źródło
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;
Prakash
źródło
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();
}
Leonel Sanches da Silva
źródło
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.

Alex Churchill
źródło
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();
}
Medo
źródło
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();
}
Sonu Dhakar
źródło
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.

yurin
źródło
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));
TMO
źródło
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.

użytkownik3359592
źródło
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();
        }
Duszan
źródło
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.

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