phpandroidjsonandroid-async-httploopj

Android / Loopj - How can i POST a complex JSON object to a server?


In one of my application, in which I use the Loopj library, I need to send a complex object to a web-service (running on PHP). I decided to send a JSON object via HTTP POST request using Loppj example.

JSONObject params = new JSONObject();

try
{
    params.put("params1", "value1");
    params.put("params2", "value2");
    params.put("params3", "value3");
}
catch(JSONException e)
{
    // ...
}

StringEntity entity = new StringEntity(params.toString(), HTTP.UTF_8);

ArrayList<Header> array = new ArrayList<>();
array.add(new BasicHeader("Content-type", "application/json"));
array.add(new BasicHeader("Accept", "application/json"));
Header[] headers = new Header[headers.size()];
headers = headers.toArray(array);

AsyncHttpClient client = new AsyncHttpClient();

client.post(context, url, headers, entity, "application/json", new JsonHttpResponseHandler()
{
    @Override
    public void onSuccess(int statusCode, Header[] headers, JSONObject response)
    {
        //...       
    }

    @Override
    public void onFailure(int statusCode, Header[] headers, Throwable e, JSONObject errorResponse)
    {
        // ...
    }
});

Unfortunately, $_POST / $_REQUEST are always empty. I've searched different tips but none of them is working. I haven't restriction on routes in my web-service, just a simple function to dump posted parameters.

EDIT 1

To check posted parameters, I coded a simple PHP page to log them. Thanks to @Steve, I was abble to find them in php://input.

file_put_contents(__DIR__ . '/post_data.log', json_encode($_POST));
file_put_contents(__DIR__ . '/input_data.log', file_get_contents('php://input'));

The fact is that I'm not the owner of the final web-services, so I can't change access to data. They must be accessible through $_POST. So, sending application/json isn't the solution ? How AJAX can send complex objects to a server and find them in $_POST, and not Android ?

EDIT 2

I tried to do the same with PostMan and $_POST is always empty. So, I analyzed the request sent by jQuery.ajax(...) (which allow you to send JSON object) and it generate proper key/value from JSON object.

For example, the JSON object :

{
    "users":[
        {
            "name":"jean",
            "age":"25",
            "city":"paris"
        }
    ]
}

It is converted in 3 pairs key/value :

So, I guess I need a function which convert my JSONObject into RequestParams object and send it "normally" through "x-www-form-urlencoded". I don't know if there's any native function which can do this but I found the Javascript equivalent (Query-string encoding of a Javascript Object).

serialize = function(obj, prefix) {
  var str = [], p;
  for(p in obj) {
    if (obj.hasOwnProperty(p)) {
      var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
      str.push((v !== null && typeof v === "object") ?
        serialize(v, k) :
        encodeURIComponent(k) + "=" + encodeURIComponent(v));
    }
  }
  return str.join("&");
}

Solution

  • As I said previously, I wrote a helper class which convert JSONObject to RequestParams which can "normally" be sent over POST HTTP method.

    I copy/paste it and wrote a quick README file. If you have any suggestions or even pull-requests, please share.

    Hope it helps.

    https://github.com/schnapse/json-to-requestparams