使用Android JSON HttpClient通过HttpResponse将数据发送到PHP服务器

23

我目前正在尝试从Android应用程序将一些数据发送到一个由我控制的php服务器。

在应用程序中收集了大量表单数据,并将其写入数据库。这一切都正常工作。

在我的主要代码中,首先我创建了一个JSONObject(为了这个示例,我已将其精简):

JSONObject j = new JSONObject();
j.put("engineer", "me");
j.put("date", "today");
j.put("fuel", "full");
j.put("car", "mine");
j.put("distance", "miles");

接下来,我将对象传递进行发送,并接收响应:

String url = "http://www.server.com/thisfile.php";
HttpResponse re = HTTPPoster.doPost(url, j);
String temp = EntityUtils.toString(re.getEntity());
if (temp.compareTo("SUCCESS")==0)
{
    Toast.makeText(this, "Sending complete!", Toast.LENGTH_LONG).show();
}
HTTPPoster类:
public static HttpResponse doPost(String url, JSONObject c) throws ClientProtocolException, IOException 
{
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost request = new HttpPost(url);
    HttpEntity entity;
    StringEntity s = new StringEntity(c.toString());
    s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
    entity = s;
    request.setEntity(entity);
    HttpResponse response;
    response = httpclient.execute(request);
    return response;
}

这里的代码可以得到一个响应,但服务器返回的是403 - 禁止访问的响应。

我尝试稍微修改了一下doPost函数(实际上这样更好,因为我有很多数据要发送,基本上是3个相同的表单,但数据不同 - 所以我创建了3个JSONObject,每个表单条目对应一个 - 条目来自DB而不是静态示例)。

首先我稍微调整了一下调用方式:

String url = "http://www.myserver.com/ServiceMatalan.php";
Map<String, String> kvPairs = new HashMap<String, String>();
kvPairs.put("vehicle", j.toString());
// Normally I would pass two more JSONObjects.....
HttpResponse re = HTTPPoster.doPost(url, kvPairs);
String temp = EntityUtils.toString(re.getEntity());
if (temp.compareTo("SUCCESS")==0)
{
    Toast.makeText(this, "Sending complete!", Toast.LENGTH_LONG).show();
}

好的,那么doPost函数的更改:

public static HttpResponse doPost(String url, Map<String, String> kvPairs) throws ClientProtocolException, IOException 
{
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost(url);
    if (kvPairs != null && kvPairs.isEmpty() == false) 
    {
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(kvPairs.size());
        String k, v;
        Iterator<String> itKeys = kvPairs.keySet().iterator();
        while (itKeys.hasNext()) 
        {
            k = itKeys.next();
            v = kvPairs.get(k);
            nameValuePairs.add(new BasicNameValuePair(k, v));
        }             
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
    }
    HttpResponse response;
    response = httpclient.execute(httppost);
    return response;
}

好的,所以这会返回一个200的响应

int statusCode = re.getStatusLine().getStatusCode();

然而,服务器接收到的数据无法解析为JSON字符串。我认为它格式不正确(这是我第一次使用JSON):

如果在php文件中对$_POST ['vehicle']执行echo操作,则会得到以下结果:

{\"date\":\"today\",\"engineer\":\"me\"}

能否有人告诉我我的错误在哪里,或者是否有更好的方法来实现我想做的事情?希望上述内容有意义!


感谢您抽出时间记录您遇到的 403 响应问题。我也遇到同样的问题一周了,但是您的帖子终于让我朝着正确的方向前进! - Toran Billups
@Toran Billups 没问题,我很高兴它对你有帮助!! - Scoobler
你的变量已经正确地提交到了 PHP 脚本。如果要将每个变量(例如“engineer”和“fuel”)插入到 MySQL 数据库中,应该如何提取它们?看起来你只能使用 $_POST['vehicle']; 变量。非常期待您的回复。 - WebDevDanno
4个回答

11

经过大量阅读和搜索,我发现问题出在服务器启用了magic_quotes_gpc。

因此,可以使用以下方法:

json_decode(stripslashes($_POST['vehicle']));

在我上面的示例中,删除了斜杠并允许正确解码JSON。

仍然不确定为什么发送StringEntity会导致403错误?


1
你能否分享一下包含 json_decode 的 PHP 文件,因为我认为我的服务器错误地解码了 JSON 数据,这可能与你的有关。 - WebDevDanno
json_decode(stripslashes($_POST['vehicle']), true); 将返回 PHP 数组,而 json_decode(stripslashes($_POST['vehicle'])); 则返回 PHP stdclass 对象,后者难以使用。答对加一分,谢谢。 - macio.Jun

4
StringEntity s = new StringEntity(c.toString());
s.setContentEncoding("UTF-8");
s.setContentType("application/json");
request.setEntity(s);

0

改变

(String url = "http://www.server.com/MainPage.php";)

(String url = "http://www.server.com/MainPage.php?";)

当您尝试将参数发送到PHP脚本时,末尾的问号是必需的。


3
谢谢Sergey,但我正在使用POST方法发送数据,而不是从PHP脚本传递GET参数。 - Scoobler

0

尝试这段代码,它完美地运行了

*For HttpClient class* download jar file "httpclient-4.3.6.jar" and put in libs folder then
Compile:   dependencies {compile files('libs/httpclient-4.3.6.jar')}

repositories {
        maven {
            url "https://jitpack.io"
        }
    }

然后像这样调用 HttpClient 类的 AsyncTask:

private class YourTask extends AsyncTask { private String error_msg = "服务器错误!";

    private JSONObject response;



    @Override
    protected Boolean doInBackground(String... params) {
        try {
            JSONObject mJsonObject = new JSONObject();
            mJsonObject.put("user_id", "user name");
            mJsonObject.put("password", "123456");
            String URL=" Your Link"

            //Log.e("Send Obj:", mJsonObject.toString());

            response = HttpClient.SendHttpPost(URL, mJsonObject);
            boolean status = response != null && response.getInt("is_error") == 0; // response

            return status;
        } catch (JSONException | NullPointerException e) {
            e.printStackTrace();
            mDialog.dismiss();
            return false;
        }
    }

    @Override
    protected void onPostExecute(Boolean status) {
       // your code

    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接