111

I'm trying to figure out how to POST JSON from Android by using HTTPClient. I've been trying to figure this out for a while, I have found plenty of examples online, but I cannot get any of them to work. I believe this is because of my lack of JSON/networking knowledge in general. I know there are plenty of examples out there but could someone point me to an actual tutorial? I'm looking for a step by step process with code and explanation of why you do each step, or of what that step does. It doesn't need to be a complicated, simple will suffice.

Again, I know there are a ton of examples out there, I'm just really looking for an example with an explanation of what exactly is happening and why it is doing that way.

If someone knows about a good Android book on this, then please let me know.

Thanks again for the help @terrance, here is the code I described below

public void shNameVerParams() throws Exception{
     String path = //removed
     HashMap  params = new HashMap();

     params.put(new String("Name"), "Value"); 
     params.put(new String("Name"), "Value");

     try {
        HttpClient.SendHttpPost(path, params);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
 }
Gaurav Gandhi
  • 2,536
  • 2
  • 23
  • 35
  • Perhaps you can post one of the examples that you cannot get working? By getting something working, you would learn how the pieces fit together. – fredw Jun 02 '11 at 17:48
  • possible duplicate of [How to send a JSON object over Request with Android?](http://stackoverflow.com/questions/3027066/how-to-send-a-json-object-over-request-with-android) – Jim G. Feb 27 '14 at 03:01

5 Answers5

157

In this answer I am using an example posted by Justin Grammens.

About JSON

JSON stands for JavaScript Object Notation. In JavaScript properties can be referenced both like this object1.name and like this object['name'];. The example from the article uses this bit of JSON.

The Parts
A fan object with email as a key and foo@bar.com as a value

{
  fan:
    {
      email : 'foo@bar.com'
    }
}

So the object equivalent would be fan.email; or fan['email'];. Both would have the same value of 'foo@bar.com'.

About HttpClient Request

The following is what our author used to make a HttpClient Request. I do not claim to be an expert at all this so if anyone has a better way to word some of the terminology feel free.

public static HttpResponse makeRequest(String path, Map params) throws Exception 
{
    //instantiates httpclient to make request
    DefaultHttpClient httpclient = new DefaultHttpClient();

    //url with the post data
    HttpPost httpost = new HttpPost(path);

    //convert parameters into JSON object
    JSONObject holder = getJsonObjectFromMap(params);

    //passes the results to a string builder/entity
    StringEntity se = new StringEntity(holder.toString());

    //sets the post request as the resulting string
    httpost.setEntity(se);
    //sets a request header so the page receving the request
    //will know what to do with it
    httpost.setHeader("Accept", "application/json");
    httpost.setHeader("Content-type", "application/json");

    //Handles what is returned from the page 
    ResponseHandler responseHandler = new BasicResponseHandler();
    return httpclient.execute(httpost, responseHandler);
}

Map

If you are not familiar with the Map data structure please take a look at the Java Map reference. In short, a map is similar to a dictionary or a hash.

private static JSONObject getJsonObjectFromMap(Map params) throws JSONException {

    //all the passed parameters from the post request
    //iterator used to loop through all the parameters
    //passed in the post request
    Iterator iter = params.entrySet().iterator();

    //Stores JSON
    JSONObject holder = new JSONObject();

    //using the earlier example your first entry would get email
    //and the inner while would get the value which would be 'foo@bar.com' 
    //{ fan: { email : 'foo@bar.com' } }

    //While there is another entry
    while (iter.hasNext()) 
    {
        //gets an entry in the params
        Map.Entry pairs = (Map.Entry)iter.next();

        //creates a key for Map
        String key = (String)pairs.getKey();

        //Create a new map
        Map m = (Map)pairs.getValue();   

        //object for storing Json
        JSONObject data = new JSONObject();

        //gets the value
        Iterator iter2 = m.entrySet().iterator();
        while (iter2.hasNext()) 
        {
            Map.Entry pairs2 = (Map.Entry)iter2.next();
            data.put((String)pairs2.getKey(), (String)pairs2.getValue());
        }

        //puts email and 'foo@bar.com'  together in map
        holder.put(key, data);
    }
    return holder;
}

Please feel free to comment on any questions that arise about this post or if I have not made something clear or if I have not touched on something that your still confused about... etc whatever pops in your head really.

(I will take down if Justin Grammens does not approve. But if not then thanks Justin for being cool about it.)

Update

I just happend to get a comment about how to use the code and realized that there was a mistake in the return type. The method signature was set to return a string but in this case it wasnt returning anything. I changed the signature to HttpResponse and will refer you to this link on Getting Response Body of HttpResponse the path variable is the url and I updated to fix a mistake in the code.

JJD
  • 44,755
  • 49
  • 183
  • 309
Terrance
  • 11,381
  • 4
  • 51
  • 78
  • Thanks @Terrance. So in a different class he is creating a map that has different keys and values that will later be turned into JSONObjects. I tried implementing something similar, but I have no experience with maps either, I'll add the code for what I tried implementing to my original post. Your explanations for what was going on made since, and I was successful in getting it to work by creating JSONObjects with hardcoded names and values. Thanks! –  Jun 03 '11 at 14:03
  • Justin says he approves. He should have enough rep to come and and leave a comment himself by now. – Abizern Jun 03 '11 at 17:52
  • I want to use this code . How do I go about this ? Please specify what is the path variable and what has to be returned so that on my java end I can fetch the data. – Prateek Jul 16 '12 at 05:29
  • the path variable is the url and the details of how to handle the Response on the last line are here. http://thinkandroid.wordpress.com/2009/12/30/getting-response-body-of-httpresponse/ – Terrance Jul 23 '12 at 18:41
  • @pKs thanks for asking the question. I just noticed that there was an issue with the code. – Terrance Jul 23 '12 at 18:42
  • So, I was working on this for about 2 hours and realized that to get an appropriate HTTP response I needed to take out the second parameter in httpclient.execute(httpost, responseHandler) -> httpclient.execute(httpost) Was not getting anything with that second parameter in there – rwarner Oct 20 '12 at 07:50
  • @Terrance my app is sending data via HttpPut method.when server got request, it reply as json data. I don't know how get data from json. please tell me. [CODE](http://pastie.org/7443759) – kongkea Apr 11 '13 at 02:05
  • 3
    There is no reason for `getJsonObjectFromMap()`: JSONObject has a constructor that takes a `Map`: http://developer.android.com/reference/org/json/JSONObject.html#JSONObject(java.util.Map) – pr1001 Aug 23 '13 at 07:58
  • @Terrance So far what you suggest is to send data to the remote server and its a nice explanation, but want to know how to parse the JSON object using HTTP protocol. Can u elaborate your answer with JSON parsing also. It will be very helpfull for everyone who is new in this. – AndroidDev Apr 07 '14 at 09:53
  • Also check out this [example for JSON at codota](https://www.codota.com/android/scenarios/52fcbd28da0a75bbf7091889/parsing-json-documents?tag=dragonfly) – drorw Jul 30 '14 at 14:16
  • Just wanted to add that setting the headers fixed it for me: httpost.setHeader("Accept", "application/json"); httpost.setHeader("Content-type", "application/json");` – Anna Billstrom Dec 19 '14 at 06:19
  • What if the json data doesnot have the fan in there? then what should remove? – Ben Jan 31 '16 at 14:24
  • You should be using reflection to write Json objects with a libaray like Gson from Google, gonna save you a lot of code and headaches. – Oliver Dixon Feb 10 '16 at 14:36
41

Here is an alternative solution to @Terrance's answer. You can easly outsource the conversion. The Gson library does wonderful work converting various data structures into JSON and the other way around.

public static void execute() {
    Map<String, String> comment = new HashMap<String, String>();
    comment.put("subject", "Using the GSON library");
    comment.put("message", "Using libraries is convenient.");
    String json = new GsonBuilder().create().toJson(comment, Map.class);
    makeRequest("http://192.168.0.1:3000/post/77/comments", json);
}

public static HttpResponse makeRequest(String uri, String json) {
    try {
        HttpPost httpPost = new HttpPost(uri);
        httpPost.setEntity(new StringEntity(json));
        httpPost.setHeader("Accept", "application/json");
        httpPost.setHeader("Content-type", "application/json");
        return new DefaultHttpClient().execute(httpPost);
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

Similar can be done by using Jackson instead of Gson. I also recommend taking a look at Retrofit which hides a lot of this boilerplate code for you. For more experienced developers I recommend trying out RxAndroid.

JJD
  • 44,755
  • 49
  • 183
  • 309
  • my app is sending data via HttpPut method.when server got request, it reply as json data. I don't know how get data from json. please tell me. [CODE](http://pastie.org/7443759). – kongkea Apr 11 '13 at 02:13
  • @kongkea Please have a look into the [GSON library](http://code.google.com/p/google-gson/). It is capable of parsing the JSON file into Java objects. – JJD Apr 11 '13 at 09:28
  • @JJD So far what you suggest is to send data to the remote server and its a nice explanation, but want to know how to parse the JSON object using HTTP protocol. Can u elaborate your answer with JSON parsing also. It will be very helpfull for everyone who is new in this. – AndroidDev Apr 07 '14 at 09:59
  • @AndroidDev Please open a **new question** since this question is about sending data from the client to the server. Feel free to drop a link here. – JJD Apr 07 '14 at 14:32
  • @JJD you are calling abstract method `execute()` and it is failed of course – Konstantin Konopko Jul 10 '14 at 11:57
  • @konopko Does not fail for me. Please open a new question if you have a specific problem to be solved. – JJD Jul 10 '14 at 13:00
  • @JJD oh, excuse me, this snipped just must be called in a separate thread – Konstantin Konopko Jul 10 '14 at 13:11
  • hi sir, if my url is a jsp page url , then how can i get the map values in that jsp? – Newinjava Jun 24 '15 at 07:45
  • @Newinjava Please open a **new question** on Stackoverflow. – JJD Jun 24 '15 at 08:53
  • How to get response returned by server – Anand Savjani Sep 24 '15 at 06:52
  • Might be a different version of the library. Please check the docs. – JJD Apr 26 '17 at 08:43
33

I recommend using this HttpURLConnectioninstead HttpGet. As HttpGet is already deprecated in Android API level 22.

HttpURLConnection httpcon;  
String url = null;
String data = null;
String result = null;
try {
  //Connect
  httpcon = (HttpURLConnection) ((new URL (url).openConnection()));
  httpcon.setDoOutput(true);
  httpcon.setRequestProperty("Content-Type", "application/json");
  httpcon.setRequestProperty("Accept", "application/json");
  httpcon.setRequestMethod("POST");
  httpcon.connect();

  //Write       
  OutputStream os = httpcon.getOutputStream();
  BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
  writer.write(data);
  writer.close();
  os.close();

  //Read        
  BufferedReader br = new BufferedReader(new InputStreamReader(httpcon.getInputStream(),"UTF-8"));

  String line = null; 
  StringBuilder sb = new StringBuilder();         

  while ((line = br.readLine()) != null) {  
    sb.append(line); 
  }         

  br.close();  
  result = sb.toString();

} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} 
ישו אוהב אותך
  • 22,515
  • 9
  • 59
  • 80
Egis
  • 849
  • 2
  • 9
  • 13
5

Too much code for this task, checkout this library https://github.com/kodart/Httpzoid Is uses GSON internally and provides API that works with objects. All JSON details are hidden.

Http http = HttpFactory.create(context);
http.get("http://example.com/users")
    .handler(new ResponseHandler<User[]>() {
        @Override
        public void success(User[] users, HttpResponse response) {
        }
    }).execute();
Arthur
  • 654
  • 1
  • 7
  • 13
3

There are couple of ways to establish HHTP connection and fetch data from a RESTFULL web service. The most recent one is GSON. But before you proceed to GSON you must have some idea of the most traditional way of creating an HTTP Client and perform data communication with a remote server. I have mentioned both the methods to send POST & GET requests using HTTPClient.

/**
 * This method is used to process GET requests to the server.
 * 
 * @param url 
 * @return String
 * @throws IOException
 */
public static String connect(String url) throws IOException {

    HttpGet httpget = new HttpGet(url);
    HttpResponse response;
    HttpParams httpParameters = new BasicHttpParams();
    // Set the timeout in milliseconds until a connection is established.
    // The default value is zero, that means the timeout is not used. 
    int timeoutConnection = 60*1000;
    HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
    // Set the default socket timeout (SO_TIMEOUT) 
    // in milliseconds which is the timeout for waiting for data.
    int timeoutSocket = 60*1000;

    HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
    HttpClient httpclient = new DefaultHttpClient(httpParameters);
    try {

        response = httpclient.execute(httpget);

        HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream instream = entity.getContent();
            result = convertStreamToString(instream);
            //instream.close();
        }
    } 
    catch (ClientProtocolException e) {
        Utilities.showDLog("connect","ClientProtocolException:-"+e);
    } catch (IOException e) {
        Utilities.showDLog("connect","IOException:-"+e); 
    }
    return result;
}


 /**
 * This method is used to send POST requests to the server.
 * 
 * @param URL
 * @param paramenter
 * @return result of server response
 */
static public String postHTPPRequest(String URL, String paramenter) {       

    HttpParams httpParameters = new BasicHttpParams();
    // Set the timeout in milliseconds until a connection is established.
    // The default value is zero, that means the timeout is not used. 
    int timeoutConnection = 60*1000;
    HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
    // Set the default socket timeout (SO_TIMEOUT) 
    // in milliseconds which is the timeout for waiting for data.
    int timeoutSocket = 60*1000;

    HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
    HttpClient httpclient = new DefaultHttpClient(httpParameters);
    HttpPost httppost = new HttpPost(URL);
    httppost.setHeader("Content-Type", "application/json");
    try {
        if (paramenter != null) {
            StringEntity tmp = null;
            tmp = new StringEntity(paramenter, "UTF-8");
            httppost.setEntity(tmp);
        }
        HttpResponse httpResponse = null;
        httpResponse = httpclient.execute(httppost);
        HttpEntity entity = httpResponse.getEntity();
        if (entity != null) {
            InputStream input = null;
            input = entity.getContent();
            String res = convertStreamToString(input);
            return res;
        }
    } 
     catch (Exception e) {
        System.out.print(e.toString());
    }
    return null;
}
Mike Clark
  • 1,774
  • 10
  • 21