【问题标题】:HttpURLConnection check whether JSON string has been inserted in mysql successfullyHttpURLConnection 检查JSON字符串是否已成功插入mysql
【发布时间】:2015-04-29 17:31:53
【问题描述】:

我实现了将 JSON 字符串发送到服务器的 android 代码。我在 doInBackground 方法中得到这个 json 字符串 '{"mac": "23:A5:J0:06:C6:E9", "latitude":84.16898451,"longitude":3.16561387,"route": 1}' 作为输出,并得到输出 getResponsecode: The output of getResponsecode: 200 在客户端的输出。

我在本地主机中检查了我的 php 文件,当我刷新 index.php 主页时,如果我更改 JSON 字符串中的某些值,则会创建总线表并更新数据。因为我使用的是公共热点,所以我无法将我的 S4 设备直接连接到本地主机来检查它。

我已经将index.php文件上传到byethost.com服务器上htdocs目录下的在线文件管理器,正在创建表总线但没有插入记录并更新。

HttpURLConnection 是否可以检查bus 表中的数据是否已成功插入/更新?我应该为file_get_contents 方法的第一个参数添加另一个路径,否则php://input

doInBackground方法:

protected Void doInBackground(String... params) {
    // TODO Auto-generated method stub

    try {
        System.out.println("The output of : doInBackground " +params[0]);

        URL myUrl = new URL("http://username.byethost8.com/index.php");
        HttpURLConnection conn = (HttpURLConnection) myUrl
                .openConnection();
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        conn.setConnectTimeout(10000);
        conn.setReadTimeout(10000);
        conn.setRequestProperty("Content-Type",
                "application/json");
        conn.connect();
        System.out.println("The output of getResponsecode: "+conn.getResponseCode());
        // create data output stream
        DataOutputStream wr = new DataOutputStream(
                conn.getOutputStream());
        // write to the output stream from the string
        wr.writeBytes(params[0]);
        wr.close();

    } catch (IOException e) {

        e.printStackTrace();
    }
    return null;

}

index.php:

    <?php
     $json = json_decode ( file_get_contents ( 'php://input', true ) );
     $con = new mysqli ( "domain.com", "user_name", "password", "database_name" );
    // I tried with this string to test the index.php file and everything works
// $json = '{"mac": "23:A5:J0:06:C6:E9", "latitude":84.16898451,"longitude":3.16561387,"route": 1}';

    $data = json_decode ( $json );

    $mac = $data->{'mac'};
    $latitude = $data->{'latitude'};
    $longitude = $data->{'longitude'};
    $route =   $data->{'route'};


    require 'connection.php';

    // check whether route's table exist.
    $results = $con->query ( "SHOW TABLES like 'bus' " ) or die ( mysqli_error () );

    if (($results->num_rows) == 1) {
      //"UPDATE MyGuests SET lastname='Doe' WHERE id=2"
     $sql = "REPLACE INTO bus(mac, route, latitude, longitude)
              VALUES( ?, ?, ? , ? )";
      $stmt = $con->prepare($sql) or die ( $con->error );
      $stmt->bind_param("ssss",$mac,$route, $latitude,$longitude);
      $stmt->execute();

      $stmt->close();

      echo "Table exist";
    } else {
      $create =  "CREATE TABLE bus
           (id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
            mac VARCHAR(30) NOT NULL UNIQUE,
            route int(11) NOT NULL,
         latitude FLOAT(10,6) NOT NULL , 
         longitude FLOAT(10,6) NOT NULL,
         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)" ;
       $stmt = $con->prepare($create) or die ( $con->error );
      $stmt->execute();

      $stmt->close();

      echo "table was created";
    }

一些 Logcat 输出:

04-29 22:18:28.541: W/System.err(32348): java.net.ProtocolException: cannot write request body after response has been read
04-29 22:18:28.541: W/System.err(32348):  at com.android.okhttp.internal.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:214)
04-29 22:18:28.551: W/System.err(32348):  at com.bustracker.MyAsyncTask.doInBackground(PostData.java:61)
04-29 22:18:28.551: W/System.err(32348):  at com.bustracker.MyAsyncTask.doInBackground(PostData.java:1)
04-29 22:18:28.551: W/System.err(32348):  at android.os.AsyncTask$2.call(AsyncTask.java:288)
04-29 22:18:28.551: W/System.err(32348):  at java.util.concurrent.FutureTask.run(FutureTask.java:237)
04-29 22:18:28.551: W/System.err(32348):  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
04-29 22:18:28.551: W/System.err(32348):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
04-29 22:18:28.551: W/System.err(32348):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
04-29 22:18:28.551: W/System.err(32348):  at java.lang.Thread.run(Thread.java:818)
04-29 22:18:28.561: I/System.out(32348): The output of : doInBackground {"mac":"89:GG:D0:06:86:M6","latitude":93.86900553,"longitude":25.66558334,"route":4}
04-29 22:18:28.591: I/System.out(32348): (HTTPLog)-Static: isSBSettingEnabled false
04-29 22:18:28.591: I/System.out(32348): KnoxVpnUidStorageknoxVpnSupported API value returned is false

【问题讨论】:

  • 看起来您在原始 PHP 代码 sn-p 中发布了真实的 MySQL 数据库登录凭据。如果是这种情况,请确保尽快更改您的 MySQL 用户密码。
  • conn.getResponseCode() 并没有过多地说明 php 脚本做了什么。您没有阅读脚本的 echo(),那么您怎么知道发生了什么?
  • @Nobu:我输入了错误的凭据,没有什么是对的 :)
  • I am getting this json string '{"mac": "23:A5:J0:06:C6:E9", "latitude":84.16898451,"longitude":3.16561387,"route": 1}' as output in the doInBackground method 。不,您将其作为 doInBackground 的输入。然后您尝试将其发送到您的脚本。但是你收到了吗? php 脚本会收到吗?你怎么检查?你根本没有检查它。你可以回显它来检查。但你不是在读那些回声。你不知道这样会发生什么。
  • 您应该发布 logcatt,因为您现在有一个 IOException。

标签: php android mysql json httpurlconnection


【解决方案1】:

您在输入时使用了两次json_decode()

您有一个 IOException cannot write request body after response has been readcaused byy 语句 System.out.println("The output of getResponsecode: "+conn.getResponseCode());。如果您还没有发送任何内容,则不能要求回复。或者更好:在那句话之后你不能再写任何东西了。将该声明放在wr.close() 之后。然后阅读回复表单conn.getInputStream()

【讨论】:

  • 我添加了一次进行测试,因为我无法将我的设备与本地主机连接,但这不是问题。我删除了它,错误仍然发生。
  • 那您为什么将答案标记为正确?每个人都会认为你的问题已经解决了!请对我所有的 cmets 做出反应。
  • 我添加了一些Logcat。
【解决方案2】:

由于mysqli_stmt::execute 返回一个布尔值,您可以使用它来使您的 PHP 页面响应某些内容(例如状态码)来指示操作是否成功(在这种情况下,您还可以提供解释对于错误)。 请注意,在这两种情况下,HTTPURLConnection 都会“成功”(这就是您得到The output of getResponsecode: 200 的原因),因为您的设备已经能够访问服务器,并且错误已经在服务器端生成。

编辑:

您得到的异常是因为您在收到响应后尝试写入输出流(即服务器)。如果您想向服务器发送一些内容,您需要在获得响应之前编写它。 因此,如果你想打印出响应,那么你需要替换这一行

DataOutputStream wr = new DataOutputStream(conn.getOutputStream());

这个

DataOutputStream wr = new DataOutputStream(conn.getInputStream());

此外,您在服务器端遇到的问题是由于您没有向服务器发送任何内容,因此您需要修复您的 android 应用程序代码

【讨论】:

  • 我如何在我的 Eclipse Android 输出中看到这个状态码?如何将其集成到代码中以在 Eclipse 中查看?
  • 服务器会响应一些东西(无论你是echo 还是print,比如这个“状态码”),你将能够通过关联到的inputStream 读取这个响应你的conn(见this link)。然后你可以像往常一样用InputStream(例如BufferedInputStream)阅读它,如果你愿意,可以打印到LogCat
  • 呃...我显然需要更多的咖啡。我删除了我所说的以减少进一步的混乱:-D 抱歉!
  • @NobuGames 别担心,没问题 ;-)
  • @但是数据在那里为什么没有发送到服务器?
猜你喜欢
  • 2018-03-30
  • 1970-01-01
  • 1970-01-01
  • 2017-01-01
  • 2012-09-02
  • 2022-11-10
  • 2013-02-13
  • 1970-01-01
  • 2016-06-30
相关资源
最近更新 更多