HTTP POST using JSON in Java
Asked Answered
R

12

226

I would like to make a simple HTTP POST using JSON in Java.

Let's say the URL is www.site.com

and it takes in the value {"name":"myname","age":"20"} labeled as 'details' for example.

How would I go about creating the syntax for the POST?

I also can't seem to find a POST method in the JSON Javadocs.

Rankle answered 24/8, 2011 at 20:1 Comment(0)
A
193

Here is what you need to do:

  1. Get the Apache HttpClient, this would enable you to make the required request
  2. Create an HttpPost request with it and add the header application/x-www-form-urlencoded
  3. Create a StringEntity that you will pass JSON to it
  4. Execute the call

The code roughly looks like (you will still need to debug it and make it work):

// @Deprecated HttpClient httpClient = new DefaultHttpClient();
HttpClient httpClient = HttpClientBuilder.create().build();
try {
    HttpPost request = new HttpPost("http://yoururl");
    StringEntity params = new StringEntity("details={\"name\":\"xyz\",\"age\":\"20\"} ");
    request.addHeader("content-type", "application/x-www-form-urlencoded");
    request.setEntity(params);
    HttpResponse response = httpClient.execute(request);
} catch (Exception ex) {
} finally {
    // @Deprecated httpClient.getConnectionManager().shutdown(); 
}
Anaheim answered 24/8, 2011 at 20:21 Comment(13)
Super. This looks quite like what I would need to write. Im trying to take a look at Apache HttpClient at hc.apache.org/httpclient-3.x/ but it seems to be down? Hmph.Rankle
So do I not actually need a JSONObject? I can just input the String directly into the StringEntity as shown above and use that?Rankle
You could but it always good practice to abstract it out as JSONObject as if you are doing directly in the string, you might program the string wrongly and causing syntax error. By using JSONObject you make sure that your serialization is always follow the right JSON structureAnaheim
That's very true, thank you for pointing that out! :) I am having another look back at this, and I'm just curious, this looks almost the same as a normal POST request, what is the difference between a normal POST request and one that is implemented for JSON?Rankle
In principal, they are both just transmitting data. The only difference is how you process it in the server. If you have only few key-value pair then a normal POST parameter with key1=value1, key2=value2, etc is probably enough, but once your data is more complex and especially containing complex structure (nested object, arrays) you would want to start consider using JSON. Sending complex structure using a key-value pair would be very nasty and difficult to parse on the server (you could try and you'll see it right away). Still remember the day when we had to do that urgh.. it wasn't pretty..Anaheim
Awesome. Thanks a ton momo! Really appreciate all the experienced information.Rankle
Glad to help! If this is what you are looking for, you should accept the answer so other people with similar questions have good lead to their questions. You can use the check mark on the answer. Let me know if you have further questionsAnaheim
Shouldn't the content-type be 'application/json'. 'application/x-www-form-urlencoded' implies the string will be formatted similar to a query string. NM I see what you did, you put the json blob as a value of a property.Robinetta
The deprecated part should be replaced by using CloseableHttpClient which gives you a .close() - method. See https://mcmap.net/q/58034/-httpclient-getconnectionmanager-is-deprecated-what-should-be-used-insteadFlitter
@mom can you please have a look on the this question [#42024658 I wrote code by looking at this answer, but I could get it working. Thanks in advanceElvinelvina
@Anaheim thank you very much. Really helped me out of a jam.Edict
For an updated version of this code: hc.apache.org/httpcomponents-client-ga/quickstart.htmlBarracoon
Android 6.0 release removes support for the Apache HTTP client. If your app is using this client and targets Android 2.3 (API level 9) or higher, use the HttpURLConnection class instead.Guv
L
105

You can make use of Gson library to convert your java classes to JSON objects.

Create a pojo class for variables you want to send as per above Example

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

becomes

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

once you set the variables in pojo1 class you can send that using the following code

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

and these are the imports

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;

and for GSON

import com.google.gson.Gson;
Lossa answered 17/1, 2014 at 4:0 Comment(8)
hi, how do you create your httpClient object? It's an interfaceVtehsta
Yes that is an Interface. You can create an instance using 'HttpClient httpClient = new DefaultHttpClient();'Lossa
now that is deprecated, we must use HttpClient httpClient = HttpClientBuilder.create().build();Vtehsta
How importing HttpClientBuilder ?Extensor
are you missed new in line 5th of the second code example? StringEntity postingString = new StringEntity(gson.toJson( new pojo1())); I have a error when I removing new.Extensor
@Lossa can you please look on this question [#42024658Elvinelvina
HttpClientBuilder is in the Maven repository: org.apache.directory.studio:org.apache.httpcomponents:4.0Prestissimo
I find it slightly cleaner to use the ContentType parameter on StringUtils constructor and pass in ContentType.APPLICATION_JSON instead of manually setting the header.Tachycardia
F
72

@momo's answer for Apache HttpClient, version 4.3.1 or later. I'm using JSON-Java to build my JSON object:

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();
}
Finlay answered 11/11, 2013 at 18:2 Comment(3)
Do we have to add content-type explicitly? will the below work? entity.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); Asking as it is not working for me. Using httpclient-4.5.1.jar.Centralization
@DarshanGopalR Yours seems to be a different way of using it. I wrote this answer 8 years ago, and didn't test newer versions of httpclient. What I would try is to stick to the example the best as you can. I can give a try in a fresh project and update the answer if necessary.Finlay
Content type should be added e.g StringEntity entity = new StringEntity(params.toString(), ContentType.APPLICATION_JSON);Logogram
L
19

It's probably easiest to use HttpURLConnection.

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

You'll use JSONObject or whatever to construct your JSON, but not to handle the network; you need to serialize it and then pass it to an HttpURLConnection to POST.

Lordly answered 24/8, 2011 at 20:6 Comment(5)
JSONObject j = new JSONObject(); j.put("name", "myname"); j.put("age", "20"); Like that? How do I serialize it?Rankle
@Rankle just use j.toString().Lordly
That's true, this connection is blocking. This probably isn't a big deal if you are sending a POST; it is much more important if you running a webserver.Lordly
The HttpURLConnection link is dead.Apices
can you post example how to post json to body?Caty
D
18
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();
}
Downatheel answered 8/9, 2015 at 13:58 Comment(1)
Please consider editing your post to add more explanation about what your code does and why it will solve the problem. An answer that mostly just contains code (even if it's working) usually won't help the OP to understand their problemMaineetloire
P
15

Try this code:

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();
}
Preventer answered 13/9, 2014 at 9:24 Comment(3)
Thanks! Only your answer solved the encoding issue :)Platyhelminth
@SonuDhakar why you send application/json both as a accept header and as content-typeElvinelvina
It seems that DefaultHttpClient is deprecated.Incase
L
13

I found this question looking for solution about how to send post request from java client to Google Endpoints. Above answers, very likely correct, but not work in case of Google Endpoints.

Solution for Google Endpoints.

  1. Request body must contains only JSON string, not name=value pair.
  2. Content type header must be set to "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();
    }
    

    It sure can be done using HttpClient as well.

Leatherette answered 13/6, 2015 at 15:27 Comment(0)
Z
11

You can use the following code with Apache HTTP:

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

response = client.execute(request);

Additionally you can create a json object and put in fields into the object like this

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));
Zap answered 2/11, 2018 at 15:9 Comment(1)
key thing is to add ContentType.APPLICATION_JSON otherwise it was not working for me new StringEntity(payload, ContentType.APPLICATION_JSON)Spellbind
O
11

For Java 11 you can use the new HTTP client:

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

You can use publishers from InputStream, String, File. Converting JSON to a String or IS can be done with Jackson.

Occur answered 17/4, 2019 at 13:47 Comment(0)
B
4

Java 11 standardization of HTTP client API that implements HTTP/2 and Web Socket, and can be found at java.net.HTTP.*:

String payload = "{\"name\": \"myname\", \"age\": \"20\"}";
HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder(URI.create("www.site.com"))
            .header("content-type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(payload))
            .build();
    
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
Bologna answered 24/10, 2021 at 14:59 Comment(0)
F
2

Java 8 with 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();
        }
Finochio answered 8/10, 2019 at 6:1 Comment(0)
O
0

I recomend http-request built on 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. 
}

If you want send JSON as request body you can:

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

I higly recomend read documentation before use.

Objectivism answered 21/9, 2017 at 11:30 Comment(2)
why do you suggest this over the above answer with the most upvotes?Houseman
Because It is very simple to use and do manipulation with response.Objectivism

© 2022 - 2024 — McMap. All rights reserved.