【问题标题】:How to pass an argument with POST using HttpUrlConnection如何使用 HttpUrlConnection 通过 POST 传递参数
【发布时间】:2015-09-28 05:20:03
【问题描述】:

编辑:我发现将 OutputStreamWriter 包装在 BufferedWriter 中会导致问题,因此去掉了包装器,我的 POST 也通过了。仍然想知道为什么是 BufferedWriter。

我提前道歉,因为我刚刚开始自学有关数据库、应用程序和服务器/数据库之间的通信以及 php 的所有知识。

提出的其他类似问题未提供答案。

在使用 HttpUrlConnection 从我的 android 应用程序到本地托管服务器上的 php 脚本进行简单 POST 时,我很难辨别我缺少什么。我需要从 android 应用程序中获取用户 ID,将其作为参数传递给 php 脚本,然后在名为 users 的数据库表中查找该 ID。我也想使用未被弃用的方法和类。

我已在 android 清单中包含 Internet 权限。我正在使用 XAMPP,并且我已验证我的服务器正在运行,如果我通过 Web 浏览器访问该 url,我会得到我正在寻找的 JSON 响应。

我唯一的 logcat 消息是 IOException,它在写入输出流之后发生。 编辑: 具体的例外是“流的意外结束”

这是我的 AsyncTask 类中的代码:

protected String doInBackground(String... params) {

    String userID = params[0];
    Pair<String, String> phpParameter = new Pair<>("userID", userID);
    String result = "";

    try {
        URL url = new URL("url of locally-hosted php script");
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

        // prepare request
        urlConnection.setRequestMethod("POST");
        urlConnection.setDoInput(true);
        urlConnection.setDoOutput(true);
        urlConnection.setReadTimeout(10000);
        urlConnection.setConnectTimeout(15000);
        urlConnection.setFixedLengthStreamingMode(userID.getBytes("UTF-8").length);

        // upload request
        OutputStream outputStream = urlConnection.getOutputStream();
        BufferedWriter writer = new BufferedWriter(
                new OutputStreamWriter(outputStream, "UTF-8"));
        writer.write(phpParameter.first + "=" + phpParameter.second);
        writer.close();
        outputStream.close();

        // read response
        BufferedReader in = new BufferedReader(
                new InputStreamReader(urlConnection.getInputStream()));

        String inputLine;
        StringBuffer response = new StringBuffer();
        while ((inputLine = in.readLine()) != null) { response.append(inputLine); }
        in.close();

        result = response.toString();

        // disconnect
        urlConnection.disconnect();
    } catch (MalformedURLException e) {
        Log.e("Malformed URL Exception", "Malformed URL Exception");
    } catch (IOException e) {
        Log.e("IOException", "IOException");
    }

    return result;
}

这是我在服务器上的 php 脚本。我还需要一些关于准备好的陈述的帮助,所以不要因为“id = 1”而责备我:

<?php

mysql_connect("host","username","password");

mysql_select_db("Database");

print($_POST);

$sql = mysql_query("select * from users where id = 1");

while($row = mysql_fetch_assoc($sql))
$output[] = $row;

print(json_encode($output)); // this will print the output in json
mysql_close();

?>

【问题讨论】:

  • only logcat message is an IOException, which occurs just after writing to the output stream。那么你应该准确地发布哪个异常。
  • 您使用 Log.e() 错误,这就是您没有获得所需信息的原因。它应该类似于Log.e("MyClassName", "my description of what went wrong", e)
  • @Dan Getz 哇,抱歉。我完全糊涂了将实际异常传递给日志。我得到“流的意外结束”。包括上面的修改以反映这一点!

标签: php android post httpurlconnection


【解决方案1】:

兄弟,使用像 loopjs async httplib 这样的自定义库会更简单。查看此代码示例,了解您要执行的操作,

你问为什么要使用它?所有异常和异步任务都在后台处理,使您的代码库更简单。

    AsyncHttpClient client = new AsyncHttpClient();
client.post(YOUR_POST_URL, new AsyncHttpResponseHandler() {

@Override
public void onStart() {
    // called before request is started
}

@Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
    // called when response HTTP status is "200 OK"
}

@Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
    // called when response HTTP status is "4XX" (eg. 401, 403, 404)
}

@Override
public void onRetry(int retryNo) {
    // called when request is retried
}
    });

【讨论】:

  • 我很欣赏使用可能更简单的外部库的建议,但我有兴趣了解我编写的代码有什么问题以及原因,而不是先跳到其他东西,因为它可能是更轻松。回答完这个问题后,我会看一下,我可以比较这两种方法。
  • 酷哥。我明白了
【解决方案2】:

从安卓发帖:

public class HttpURLConnectionHandler
{
     protected String urlG = "http://192.168.43.98/yourdirectory/";
     public String sendText(String text)
    {
    try {
        URL url = new URL(urlG+"receiveData.php");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");

        // para activar el metodo post
        conn.setDoOutput(true);
        conn.setDoInput(true);
        DataOutputStream wr = new DataOutputStream(
            conn.getOutputStream());
        wr.writeBytes("mydata="+text);
        wr.flush();
        wr.close();

        InputStream is = conn.getInputStream();
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));
        String line;
        StringBuffer response = new StringBuffer();
        while((line = rd.readLine()) != null) {
            response.append(line);
            response.append('\r');
        }
        rd.close();
        return response.toString();
   }
   catch(Exception e){ return "error";}
   }
}

php 文件:

$x = $_POST['mydata'];
echo $x;  

【讨论】:

  • 感谢您的回复,但我在问题中提到我想使用未弃用的方法和类。根据 Android 开发者文档,HttpClient、HttpPost、HttpResponse 等在 API 级别 22 中已弃用。
  • httpclient 已弃用
  • @Rene Okay 看到了
【解决方案3】:

看来我修好了!

我变了

BufferedWriter writer = new BufferedWriter(
            new OutputStreamWriter(outputStream, "UTF-8"));
writer.write(phpParameter.first + "=" + phpParameter.second);

OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
writer.write(userID);

出于某种原因,将输出流写入器包装在缓冲写入器中的行为破坏了它。我不知道为什么。

完成上述更改后,我收到一条错误消息,指出流需要 1 个字节,但收到了 8 个字节,所以我只写了 userID,这就是我传递给 setFixedLengthStreamingMode 的内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-02
    • 1970-01-01
    • 1970-01-01
    • 2019-10-17
    • 1970-01-01
    相关资源
    最近更新 更多