HTTP POST usando JSON em Java

188

Gostaria de fazer um HTTP POST simples usando JSON em Java.

Digamos que o URL seja www.site.com

e recebe o valor {"name":"myname","age":"20"}rotulado como 'details'por exemplo.

Como eu criaria a sintaxe para o POST?

Também não consigo encontrar um método POST nos Javadocs JSON.

asdf007
fonte

Respostas:

167

Aqui está o que você precisa fazer:

  1. Obtenha o Apache HttpClient, isso permitirá que você faça a solicitação necessária
  2. Crie uma solicitação HttpPost com ela e adicione o cabeçalho "application / x-www-form-urlencoded"
  3. Crie um StringEntity que você passará JSON para ele
  4. Executar a chamada

O código parece mais ou menos (você ainda precisará depurá-lo e fazê-lo funcionar)

//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
fonte
9
Você pode, mas sempre é uma boa prática abstraí-lo como JSONObject, como se estivesse fazendo diretamente na sequência, pode programar a sequência incorretamente e causar erro de sintaxe. Usando JSONObject você se certificar de que a sua serialização é sempre seguir a estrutura JSON direito
momo
3
Principalmente, ambos estão apenas transmitindo dados. A única diferença é como você a processa no servidor. Se você tiver apenas alguns pares de valores-chave, um parâmetro POST normal com chave1 = valor1, chave2 = valor2, etc. provavelmente será suficiente, mas uma vez que seus dados sejam mais complexos e contenham estrutura complexa (objeto aninhado, matrizes), você desejará comece a considerar o uso de JSON. Enviar uma estrutura complexa usando um par de valores-chave seria muito desagradável e difícil de analisar no servidor (você pode tentar e verá isso imediatamente). Ainda me lembro do dia em que tive que fazer isso urgh .. ele não era bonita ..
momo
1
Feliz em ajudar! Se é isso que você está procurando, você deve aceitar a resposta para que outras pessoas com perguntas semelhantes tenham uma boa orientação para elas. Você pode usar a marca de seleção na resposta. Deixe-me saber se você tem mais perguntas
momo
12
O tipo de conteúdo não deve ser 'application / json'. 'application / x-www-form-urlencoded' implica que a string será formatada de forma semelhante a uma string de consulta. NM Entendo o que você fez, você coloca o json blob como o valor de uma propriedade.
Matthew Ward
1
A peça obsoleta deve ser substituída usando o CloseableHttpClient, que fornece um método .close () -. Veja stackoverflow.com/a/20713689/1484047
Frame91
92

Você pode usar a biblioteca Gson para converter suas classes java em objetos JSON.

Crie uma classe pojo para variáveis ​​que você deseja enviar conforme o exemplo acima

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

torna-se

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

Depois de definir as variáveis ​​na classe pojo1, você pode enviá-lo usando o seguinte código

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

e estas são as importações

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;

e para GSON

import com.google.gson.Gson;
Prakash
fonte
1
oi, como você cria seu objeto httpClient? É uma interface
user3290180
1
Sim, isso é uma interface. Você pode criar uma instância usando 'HttpClient httpClient = new DefaultHttpClient ();'
Prakash
2
agora que foi preterido, devemos usar HttpClient httpClient = HttpClientBuilder.create (). build ();
user3290180
5
Como importar HttpClientBuilder?
precisa saber é o seguinte
3
Acho um pouco mais limpo usar o parâmetro ContentType no construtor StringUtils e passar o ContentType.APPLICATION_JSON em vez de definir manualmente o cabeçalho.
TownCube
47

A resposta da @ momo para o Apache HttpClient, versão 4.3.1 ou posterior. Estou usando JSON-Javapara criar meu objeto 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
fonte
20

Provavelmente é mais fácil usar o HttpURLConnection .

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

Você usará JSONObject ou o que quer que seja para construir seu JSON, mas não para lidar com a rede; você precisa serializá-lo e depois passá-lo para uma HttpURLConnection para POST.

Alex Churchill
fonte
JSONObject j = novo JSONObject (); j.put ("nome", "meu nome"); j.put ("idade", "20"); Curtiu isso? Como serializá-lo?
precisa saber é o seguinte
@ asdf007 basta usar j.toString().
Alex Churchill
Isso é verdade, essa conexão está bloqueando. Provavelmente isso não é grande coisa se você estiver enviando um POST; é muito mais importante se você estiver executando um servidor da web.
Alex Churchill
O link HttpURLConnection está inoperante.
amigos estão dizendo sobre tobias roland
você pode postar exemplo como postar json no corpo?
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
fonte
7
Considere editar sua postagem para adicionar mais explicações sobre o que seu código faz e por que ele resolverá o problema. Uma resposta que na maior parte apenas contém código (mesmo se ele está funcionando) geralmente não vai ajudar o OP para compreender o seu problema
Reeno
14

Tente este código:

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
fonte
Obrigado! Apenas a sua resposta resolvido o problema de codificação :)
Shrikant
@SonuDhakar por que você enviar application/jsontanto como um cabeçalho aceitar e como Content-Type
Kasun Siyambalapitiya
Parece que DefaultHttpClientestá obsoleto.
Sdgfsdh
11

Encontrei esta pergunta procurando uma solução sobre como enviar uma solicitação de postagem do cliente java para o Google Endpoints. Respostas acima, provavelmente corretas, mas não funcionam no caso de pontos finais do Google.

Solução para pontos finais do Google.

  1. O corpo da solicitação deve conter apenas a sequência JSON, não o nome = par de valor.
  2. O cabeçalho do tipo de conteúdo deve estar definido como "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();
    }

    Isso também pode ser feito usando o HttpClient.

yurin
fonte
8

Você pode usar o seguinte código com o Apache HTTP:

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

response = client.execute(request);

Além disso, você pode criar um objeto json e inserir campos no objeto como este

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
fonte
a principal coisa é adicionar ContentType.APPLICATION_JSON, caso contrário não estava funcionando para mim nova StringEntity (carga útil, ContentType.APPLICATION_JSON)
Johnny Cage
2

Para Java 11, você pode usar o novo cliente 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();

Você pode usar o editor de InputStream, String, File. Convertendo JSON para a String ou IS você pode com Jackson.

user3359592
fonte
1

Java 8 com 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();
        }
Dushan
fonte
0

Eu recomendo o http-request construído no 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. 
}

Se você deseja enviar JSONcomo corpo de solicitação, pode:

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

Eu recomendo ler a documentação antes de usar.

Beno Arakelyan
fonte
por que você sugere isso acima da resposta acima com mais votos?
Jeryl Cook
Porque é muito simples de usar e manipular com resposta.
Beno Arakelyan 11/01/19