HttpURLConnection 检查 JSON 字符串是否已成功插入 mysql
HttpURLConnection check whether JSON string has been inserted in mysql successfully
我实现了 android 代码以将 JSON 字符串发送到服务器。我在 doInBackground 方法中得到这个 json 字符串 '{"mac": "23:A5:J0:06:C6:E9", "latitude":84.16898451,"longitude":3.16561387,"route": 1}'
作为输出,并且在客户端得到输出 The output of getResponsecode: The output of getResponsecode: 200
.
我检查了我在本地主机中的 php 文件,当我刷新 index.php 主页时,正在创建总线 table 并且如果我在 JSON 字符串。我无法将我的 S4 设备直接连接到本地主机来检查它,因为我正在使用 public 热点。
我已将 index.php
文件上传到 byethost.com 服务器上 htdocs
目录中的在线文件管理器,正在创建 table 总线,但没有插入记录然后更新。
是否可以通过HttpURLConnection检查数据是否已经inserted/updated在bus
table中成功?我是否应该为 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.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.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
由于 mysqli_stmt::execute
returns 是一个布尔值,您可以使用它来使您的 PHP 页面响应某些内容(例如状态代码)以指示操作是否成功或不(在这种情况下,您还可以提供错误的解释)。
请注意,在这两种情况下,HTTPURLConnection 都将为 "successful"(这就是您获得 The output of getResponsecode: 200
的原因),因为您的设备已经能够访问服务器,并且服务器端已生成错误。
编辑:
你得到的异常是因为你试图在获得响应后写入输出流(即服务器)。如果您想向服务器发送一些内容,您需要在获得响应之前将其写入。
因此,如果你想打印出响应,那么你需要替换这一行
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
用这个
DataOutputStream wr = new DataOutputStream(conn.getInputStream());
此外,您在服务器端遇到的问题是由于您没有向服务器发送任何内容,因此您需要修复 android 应用程序代码
您在输入中使用了两次 json_decode()
。
您有一个 IOException cannot write request body after response has been read
由语句 System.out.println("The output of getResponsecode: "+conn.getResponseCode());
引起。如果您还没有发送任何内容,则不能要求回复。或者更好:在那句话之后你不能再写任何东西了。将该语句放在 wr.close()
之后。然后阅读回复表 conn.getInputStream()
.
我实现了 android 代码以将 JSON 字符串发送到服务器。我在 doInBackground 方法中得到这个 json 字符串 '{"mac": "23:A5:J0:06:C6:E9", "latitude":84.16898451,"longitude":3.16561387,"route": 1}'
作为输出,并且在客户端得到输出 The output of getResponsecode: The output of getResponsecode: 200
.
我检查了我在本地主机中的 php 文件,当我刷新 index.php 主页时,正在创建总线 table 并且如果我在 JSON 字符串。我无法将我的 S4 设备直接连接到本地主机来检查它,因为我正在使用 public 热点。
我已将 index.php
文件上传到 byethost.com 服务器上 htdocs
目录中的在线文件管理器,正在创建 table 总线,但没有插入记录然后更新。
是否可以通过HttpURLConnection检查数据是否已经inserted/updated在bus
table中成功?我是否应该为 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.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.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
由于 mysqli_stmt::execute
returns 是一个布尔值,您可以使用它来使您的 PHP 页面响应某些内容(例如状态代码)以指示操作是否成功或不(在这种情况下,您还可以提供错误的解释)。
请注意,在这两种情况下,HTTPURLConnection 都将为 "successful"(这就是您获得 The output of getResponsecode: 200
的原因),因为您的设备已经能够访问服务器,并且服务器端已生成错误。
编辑:
你得到的异常是因为你试图在获得响应后写入输出流(即服务器)。如果您想向服务器发送一些内容,您需要在获得响应之前将其写入。 因此,如果你想打印出响应,那么你需要替换这一行
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
用这个
DataOutputStream wr = new DataOutputStream(conn.getInputStream());
此外,您在服务器端遇到的问题是由于您没有向服务器发送任何内容,因此您需要修复 android 应用程序代码
您在输入中使用了两次 json_decode()
。
您有一个 IOException cannot write request body after response has been read
由语句 System.out.println("The output of getResponsecode: "+conn.getResponseCode());
引起。如果您还没有发送任何内容,则不能要求回复。或者更好:在那句话之后你不能再写任何东西了。将该语句放在 wr.close()
之后。然后阅读回复表 conn.getInputStream()
.