3

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; 
?> 
asked Mar 2, 2011 at 0:19

3 Answers 3

8

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');
answered Mar 2, 2011 at 0:28
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you Jeff. I just used the snippet that Saurav offered for your first choice (process raw data on the php side) and it works just like you mention. In your opinion, is there a generally accepted 'right' answer to your choice? I am tempted to do the formatting on the android side, but clearly didn't do it correctly the first time. Would you be able to do it using JSONObject instead of List? Thanks again for your help. ctgScott
Both choices are valid, as long as they don't make you do anything evil. If you needed to include some parameters outside the JSON, for example encoding preferences, encryption properties, security hash, etc, then name value pairs are a better fit ... since that isn't the case, accessing the raw post data is fine.
I may not have made the example clear, but ... the "se" value in the nameValuePairs.add call is the JSONObject (that's the local parameter name you gave it), so in a sense, it does use the JSON object, just inside the list.
4

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'];
 }
}
answered Mar 2, 2011 at 0:28

2 Comments

Ohhh! Thank you Saurav! It works perfectly. Is this the appropriate way to handle JSON coming from Java? Or is there another way to construct the JSONObject so that it is automatically grabbed by $_POST? I have worked with json_encode/json_decode in php and was able to post directly from forms but this is my first time coming from android.
I've always used the NameValuePair way of posting data. That way I can add other post variables in later releases without breaking the code. But honestly, I'm of the opinion if it works... it works. Focus on pushing usable stuff out quickly rather than sweating details. At the end of the day, if no one uses your software it doesn't matter how nicely it was written (IMHO).
4

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");
 }
 }
}
answered Mar 2, 2011 at 23:20

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.