在Android/Java中使用AsyncTask发出HTTP POST请求的问题


Trouble with Making HTTP POST requests using AsyncTask in Android/Java

简而言之,我遇到的问题有两个方面;我的请求没有将其数据发布到服务器,AsyncTask似乎在每次执行中执行多次。我会详细说明。。。

我正在使用我用PHP编写的web服务开发一个应用程序。在我的应用程序代码中,我有触发请求处理程序new HTTPRequestHandler().execute("myurl.php","POST"); 的事件

问题几乎可以肯定地存在于这些代码行之间:

try {
     json.put("test", uri[1]);
     Log.d("Testing", uri[1]);
     StringEntity httpPost = new StringEntity(json.toString(), HTTP.UTF_8);
     httpPost.setContentType("application/json");
     post.setEntity(httpPost);
     httpclient.execute(post);
     result = "Success";
     } catch (JSONException e) {
         //some Error logging(e);
     }

它似乎根本没有在请求中附加任何URL参数,因此没有数据发送到我的服务器。这是我的RequestHandler 代码

公共类HTTPRequestHandler扩展AsyncTask{

final String key = "?key=verylongkey";
@Override
public String doInBackground(String... uri) {
    String verb = uri[1];
    HttpClient httpclient = new DefaultHttpClient();
    HttpResponse response;
    InputStream inputStream = null;
    StringBuilder stringbuilder = new StringBuilder();
    String result = null;
//begin GET request
    if(verb.equals("GET")){
        //functional code for get; prints desired results
        }
//begin POST request
    }else if(verb.equals("POST")){
        HttpPost post = new HttpPost(uri[0]+key);
        JSONObject json = new JSONObject();
        try {
            json.put("test", uri[1]);
            Log.d("Testing", uri[1]);
            StringEntity httpPost = new StringEntity(json.toString(), HTTP.UTF_8);
            httpPost.setContentType("application/json");
            post.setEntity(httpPost);
            httpclient.execute(post);
            result = "Success";
        } catch (JSONException e) {
            Log.e("Testing", "Execution failure: exception: ", e);
        } catch (UnsupportedEncodingException e){
            Log.e("Testing", "Execution failure: exception: ", e);
        } catch (ClientProtocolException e) {
            Log.e("Testing", "Execution failure: exception: ", e);
        } catch (IOException e) {
            Log.e("Testing", "Execution failure: exception: ", e);
        }
        //endregion
    }else{
        result = "no valid method specified";
    }
    return result;
}
@Override
public void onPostExecute(String result){
    super.onPostExecute(result);
    JSONObject jsonObject;
    try {
        jsonObject = new JSONObject(result);
        List<String> stuff =new ArrayList<String>();
        JSONArray cast = jsonObject.getJSONArray("Results");
        for (int i=0;i<cast.length();i++){
            JSONObject json_data = cast.getJSONObject(i);
            Log.d("Testing", "Array["+i+"]"+json_data.getString("mykey"));
        }
    }catch(JSONException e) {
        Log.e("Testing", "Execution failure: exception: ", e);
    }
}
}

我正在编写代码,其中记录了有关POST请求的一些信息,但一旦帖子真正工作起来,我就会了解到这一点。我的PHP是这样的:

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('default_charset', 'UTF-8');
//non-empty credential strings
$server = '';
$user = '';
$pass = '';
$dbname = '';
if ($_GET['key'] == "HwLpn88NZcb8LaCYTKaLFRpUZuGRfP92HB8DJYQvdPQEeKZWBNDkprnfzmzjP8cMsUJCpvXb") {  
    $con = mysqli_connect($server, $user, $pass, $dbname);
    if (!$con) {
        die("Connection failure: " . $con -> connect_error);
    } else {
        if (!empty($_GET["test"])) {
            $value = $_GET["test"];
            echo $value;
            $insert = mysqli_query($con, "INSERT INTO table (column) VALUES ('$value')");
            if($insert){
                echo "inserted";
            }
        } else {
            //assume functional non-post request code which prints desired data
        }
    }
    $con -> close();
}
?>

在我的浏览器中用url参数&test=somevalue点击这个url,我可以在我的数据库中看到数据实际上是在发布的,因为$_GET["test"]不是空的;

上面的大部分代码都来自我看过的教程和其他帖子。我不敢相信在2015年没有更简单的方法可以做到这一点,所以如果你看到这个想法"为什么不使用这个库,让你的请求有5行代码?"请启发我。

更新

好的,现在我在我的PHP中尝试$_POST["mykey"],我已经更新了我的Java,如下所示:

JSONObject json = new JSONObject();
    json.put("test","65481");
     url = new URL (uri[0]+key);
     urlConn = url.openConnection();
     urlConn.setDoInput(true);
     urlConn.setDoOutput(true);
     urlConn.setUseCaches(false);
     urlConn.setRequestProperty("Content-Type", "application/json");
     urlConn.setRequestProperty("Host", "android.schoolportal.gr");
     urlConn.connect();
     // as per the suggested comment
     printout = new DataOutputStream(urlConn.getOutputStream());
     byte[] data=json.toString().getBytes("UTF-8");
     printout.write(data);
     printout.flush();
     printout.close();
     result="Post Success";

但我仍然没有得到职位。根据评论者的建议,使用这种形式的代码来获得PHP响应的好方法是什么?

我在发送Java代码和接收PHP代码之间的通信有点不匹配。因为我发送的是JSON,所以我必须这么说,并将发布的数据json_decode。同样重要的是要注意,尽管连接可能已经打开,但在我读取数据之前,POST不会完成。

PHP

if (file_get_contents('php://input') != false) {
    $data = json_decode(file_get_contents('php://input'), true);
    $value = $data["test"];
    echo $value;
    $insert = mysqli_query($con, "INSERT INTO mytable (mycolumn) VALUES ('$value')");
    if($insert){
        echo "Success";
}

JAVA

JSONObject json = new JSONObject();
json.put("test","65481");
url = new URL (uri[0]+key);
urlConn = url.openConnection();
urlConn.setDoInput(true);
urlConn.setDoOutput(true);
urlConn.setUseCaches(false);
urlConn.connect();
printout = new DataOutputStream(urlConn.getOutputStream());
byte[] data=json.toString().getBytes("UTF-8");
printout.write(data);
input = new DataInputStream(urlConn.getInputStream());
StringBuffer inputLine = new StringBuffer();
String tmp;
//it seems until input.readLine() is called, the POST would not execute
while ((tmp = input.readLine()) != null){
    inputLine.append(tmp);
    Log.d("Testing","Contents:"+tmp);
}
printout.flush();
printout.close();
result="Post Success";