I am having trouble getting an android POST of a simple JSONObject to show up in the $_POST data on the server. The server is PHP 5.3.4 and the android side is an SDK 8 emulator. I can post a simple NameValuePair as normal and it shows up but when I switch to the JSONObject + StringEntity that you see below the $_POST array shows { }. Go ahead and run the code below against my test php page. It has a var_dump of $_POST and $_SERVER as well as searching for one of the expected keys ('email'). You will see I have tried numerous 'ContentType's to see if that was the problem. I've even used WireShark to verify that the TCP conversation looks good between client and server. The POST data is in there but it isn't showing up in the server's vars. I am stuck... thanks for any help you can offer.
import java.io.InputStream;
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.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.json.JSONObject;
import android.util.Log;
public class TestPOST {
protected static void sendJson (final String email, final String pwd) {
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); //Timeout Limit
HttpResponse response;
String URL = "http://web-billings.com/testPost.php";
try{
HttpPost post = new HttpPost(URL);
// NameValuePair That is working fine...
//List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
//nameValuePairs.add(new BasicNameValuePair("email", email));
//nameValuePairs.add(new BasicNameValuePair("password", pwd));
//post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
//Log.i("main", "P2DB - String entity 'se' = "+nameValuePairs.toString());
JSONObject jObject = new JSONObject();
jObject.put("email", email);
jObject.put("password", pwd);
StringEntity se = new StringEntity(jObject.toString());
//se.setContentType("charset=UTF-8");
se.setContentType("application/json;charset=UTF-8");
//se.setContentType("application/json");
//se.setContentType("application/x-www-form-urlencoded");
post.setEntity(se);
Log.i("main", "TestPOST - String entity 'se' = "+GetInvoices.convertStreamToString(se.getContent()));
response = client.execute(post);
/*Checking response */
if(response!=null){
InputStream in = response.getEntity().getContent(); //Get the data in the entity
String message = GetInvoices.convertStreamToString(in);
Log.i("main", "P2DB - Connect response = "+message);
}
}
catch(Exception e){
e.printStackTrace();
//createDialog("Error", "Cannot Establish Connection");
}
}
}
Here is the testPost.php page if you like:
<?php
echo "\r\n<pre>\r\n";
var_dump("\$_POST = ", $_POST)."\r\n";
echo '$_POST[\'email\'] = '.$_POST['email']."\r\n";
var_dump("\$_SERVER = ", $_SERVER)."\r\n";
echo '</pre>';
die;
?>
3 Answers 3
From what I can see, HttpPost.setEntity sets the body of the request without any name/value pairings, just raw post data. $_POST doesn't look for raw data, just name value pairs, which it converts into a hashtable/array. You have two choices ... either process the raw post data, or format the request such that it includes name value pairs.
Android/Java, name value pair example:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://web-billings.com/testPost.php");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("jsondata", se));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
Raw post data access in PHP:
$json = file_get_contents('php://input');
3 Comments
You're posting a json string as one big value to a post variable. So you'll need to grab the json string on the server and convert it to an object before you can access the data in the json from PHP.
$jsonString = file_get_contents('php://input');
$jsonObj = json_decode($jsonString, true);
if( !empty($jsonObj)) {
try {
$email = $jsonObj['email'];
$password = $jsonObj['password'];
}
}
2 Comments
Thanks much to Jeff Parker and Saurav for identifying the issue of either: 1) set a name/value pair on the android side, or 2) parse the raw input on the PHP side. Because of their advice here is a much cleaner and running version of the original code. I pass in a JSONObject in this boiled down copy because that is what I am doing in my real code and there are lots of things to do to make this really sea worthy but these are the basic working parts:
public class TestPOST2 {
protected static void sendJson (final JSONObject json) {
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); //Timeout Limit
HttpResponse response;
String URL = "http://web-billings.com/testPost.php";
try{
HttpPost post = new HttpPost(URL);
// Create a NameValuePair out of the JSONObject + a name
List<NameValuePair> nVP = new ArrayList<NameValuePair>(2);
nVP.add(new BasicNameValuePair("json", json.toString()));
// Hand the NVP to the POST
post.setEntity(new UrlEncodedFormEntity(nVP));
Log.i("main", "TestPOST - nVP = "+nVP.toString());
// Collect the response
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();
//createDialog("Error", "Cannot Establish Connection");
}
}
}