【问题标题】:problem POSTing android JSONObject to PHP将android JSONObject发布到PHP的问题
【发布时间】:2011-03-02 00:19:26
【问题描述】:

我无法让简单 JSONObject 的 android POST 显示在服务器上的 $_POST 数据中。服务器是 PHP 5.3.4,android 端是 SDK 8 模拟器。我可以像往常一样发布一个简单的 NameValuePair,它会显示出来,但是当我切换到您在 $_POST 数组下方看到的 JSONObject + StringEntity 时,它会显示 {}。继续并针对我的测试 php 页面运行下面的代码。它具有 $_POST 和 $_SERVER 的 var_dump 以及搜索预期密钥之一(“电子邮件”)。你会看到我已经尝试了很多'ContentType'来看看这是否是问题所在。我什至使用 WireShark 来验证客户端和服务器之间的 TCP 对话是否正常。 POST 数据在那里,但它没有显示在服务器的变量中。我被困住了...感谢您提供的任何帮助。

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

如果你喜欢,这里是 testPost.php 页面:

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

【问题讨论】:

    标签: php android json post


    【解决方案1】:

    据我所知,HttpPost.setEntity 设置了请求的主体,没有任何名称/值对,只是原始的发布数据。 $_POST 不查找原始数据,只查找名称值对,并将其转换为哈希表/数组。您有两个选择...要么处理原始帖子数据,要么格式化请求以使其包含名称值对。

    Android/Java,名称值对示例:

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

    PHP 中的原始帖子数据访问:

    $json = file_get_contents('php://input');
    

    【讨论】:

    • 谢谢杰夫。我刚刚使用了 Saurav 为您的首选提供的 sn-p(在 php 端处理原始数据),它就像您提到的那样工作。在您看来,您的选择是否存在普遍接受的“正确”答案?我很想在 android 端进行格式化,但显然第一次没有正确完成。您可以使用 JSONObject 而不是 List 来做到这一点吗?再次感谢你的帮助。 ctgScott
    • 这两种选择都是有效的,只要它们不会让你做任何坏事。如果您需要在 JSON 之外包含一些参数,例如编码首选项、加密属性、安全哈希等,那么名称值对更适合......因为情况并非如此,所以访问原始帖子数据就可以了.
    • 我可能没有把这个例子说清楚,但是...... nameValuePairs.add 调用中的“se”值是 JSONObject(这是你给它的本地参数名称),所以在某种意义上,它确实使用了 JSON 对象,就在列表中。
    【解决方案2】:

    您将 json 字符串作为一个大值发布到 post 变量。因此,您需要在服务器上获取 json 字符串并将其转换为对象,然后才能从 PHP 访问 json 中的数据。

    $jsonString = file_get_contents('php://input');
    $jsonObj = json_decode($jsonString, true);
    
    if( !empty($jsonObj)) { 
        try {
            $email = $jsonObj['email'];
            $password = $jsonObj['password'];
        }
    }
    

    【讨论】:

    • 哦!谢谢你,索拉夫!它完美地工作。这是处理来自 Java 的 JSON 的适当方法吗?还是有另一种方法来构造 JSONObject 以便它被 $_POST 自动抓取?我在 php 中使用过 json_encode/json_decode 并且能够直接从表单中发布,但这是我第一次来自 android。
    • 我一直使用 NameValuePair 方式发布数据。这样我就可以在以后的版本中添加其他帖子变量而不会破坏代码。但老实说,我认为如果它有效......它有效。专注于快速推出可用的东西,而不是出汗的细节。归根结底,如果没有人使用您的软件,那么它写得有多好都没关系(恕我直言)。
    【解决方案3】:

    非常感谢 Jeff Parker 和 Saurav 确定以下任一问题:1) 在 android 端设置名称/值对,或 2) 在 PHP 端解析原始输入。由于他们的建议,这里是原始代码的更清洁和可运行的版本。我在这个精简的副本中传递了一个 JSONObject,因为这就是我在我的真实代码中所做的事情,并且有很多事情要做才能使这个真正具有海洋价值,但这些是基本的工作部分:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      • 1970-01-01
      • 1970-01-01
      • 2013-10-02
      相关资源
      最近更新 更多