Android应用向PHP服务器发送JSON数据失败求助
看起来你遇到的情况确实有点挠头——Android端明明返回了HTTP_OK,但PHP服务器就是没接收到JSON数据。我帮你梳理下两端代码里的问题点,以及对应的修复方案:
一、Android端代码的问题与修复
你的Android代码里有几个细节处理不当,可能导致数据没有正确发送到服务器:
数据流操作顺序错误
你在写入数据到bufferedWriter之前,先调用了outputStream.flush();,这时候输出流是空的,flush没有意义,反而可能干扰后续数据的提交。正确顺序应该是先写入数据,再刷新缓冲。内容长度计算未指定编码
setFixedLengthStreamingMode使用params[1].getBytes().length时,默认会采用平台编码(不一定是UTF-8),但你请求头指定的是Content-Type: application/json,这会导致长度计算不匹配,服务器可能截断或无法识别数据。资源未正确回收
当前关闭流的逻辑放在响应码判断之后,如果提前return(比如收到HTTP_OK就返回true),流和连接都不会被关闭,既可能造成资源泄漏,也可能影响数据的完整发送。
修改后的Android代码:
@Override protected Boolean doInBackground(String... params) { HttpURLConnection httpURLConnection = null; OutputStream outputStream = null; BufferedWriter bufferedWriter = null; try { URL url = new URL(params[0]); httpURLConnection = (HttpURLConnection) url.openConnection(); httpURLConnection.setDoInput(true); httpURLConnection.setDoOutput(true); httpURLConnection.setRequestMethod("POST"); // 指定UTF-8编码计算内容长度,和请求头保持一致 byte[] postData = params[1].getBytes("UTF-8"); httpURLConnection.setFixedLengthStreamingMode(postData.length); httpURLConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); httpURLConnection.connect(); outputStream = new BufferedOutputStream(httpURLConnection.getOutputStream()); bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8")); // 先写入数据,再依次刷新缓冲和输出流 bufferedWriter.write(params[1]); bufferedWriter.flush(); outputStream.flush(); int httpResponse = httpURLConnection.getResponseCode(); Log.d("TAG", "Response Code: " + httpResponse); if (httpResponse == HttpURLConnection.HTTP_OK || httpResponse == HttpURLConnection.HTTP_ACCEPTED) { Log.d("TAG", "Data sent successfully"); return true; } else { Log.d("TAG", "Unexpected response code: " + httpResponse); return false; } } catch (IOException e) { e.printStackTrace(); return false; } finally { // 在finally块中确保所有资源被关闭,避免泄漏 try { if (bufferedWriter != null) bufferedWriter.close(); if (outputStream != null) outputStream.close(); if (httpURLConnection != null) httpURLConnection.disconnect(); } catch (IOException e) { e.printStackTrace(); } } }
另外,生成JSON数组的代码还有个隐藏bug:你在循环里重复使用同一个JSONObject对象,会导致所有数组元素都是最后一条记录的数据。把对象创建放到循环内部即可:
JSONArray jsonArray = new JSONArray(); for (Record record : list) { try { // 每次循环创建新的JSONObject,避免数据覆盖 JSONObject jsonObject = new JSONObject(); jsonObject.put("firstName", record.getFirstName()); jsonObject.put("lastName", record.getLastName()); jsonObject.put("age", String.valueOf(record.getAge())); jsonObject.put("sex", record.getSex()); jsonObject.put("comment", record.getComment()); jsonArray.put(jsonObject); } catch (JSONException e) { e.printStackTrace(); } }
二、PHP端代码的问题与修复
即使数据正确发送,你的PHP脚本也可能因为以下问题无法处理:
缺少JSON解析错误处理
如果file_get_contents('php://input')读取失败,或者JSON格式错误,json_decode会返回null,但你的代码直接跳过逻辑,没有任何错误提示,根本不知道问题出在哪。SQL语句存在语法错误与注入风险
字符串类型的字段(比如firstName、lastName)没有用单引号包裹,会直接导致SQL语法错误;同时直接拼接用户输入到SQL里,存在严重的SQL注入风险。缺少调试信息
没有打印接收到的原始数据,无法确认服务器是否真的收到了JSON。
修改后的PHP代码:
<?php echo "PHP script started<br>"; // 打印接收到的原始数据,方便调试 $jsonInput = file_get_contents('php://input'); echo "Received input: " . $jsonInput . "<br>"; // 检查JSON解析是否成功 $objs = json_decode($jsonInput); if (json_last_error() !== JSON_ERROR_NONE) { echo "JSON parse error: " . json_last_error_msg() . "<br>"; exit; } // 确认解析结果是数组 if (is_array($objs)) { $servername = "localhost"; $username = "root"; $password = ""; $dbname = "Synch"; // 创建数据库连接 $conn = new mysqli($servername, $username, $password, $dbname); if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } // 使用预处理语句防止SQL注入,同时解决字符串字段的语法问题 $sql = "INSERT INTO Synchdata (firstName, lastName, age, sex, comment) VALUES (?, ?, ?, ?, ?)"; $stmt = $conn->prepare($sql); if (!$stmt) { echo "Prepare statement error: " . $conn->error . "<br>"; $conn->close(); exit; } // 绑定参数(s表示字符串,若age是整数类型可改为i) $stmt->bind_param("sssss", $firstName, $lastName, $age, $sex, $comment); foreach ($objs as $obj) { $firstName = $obj->firstName; $lastName = $obj->lastName; $age = $obj->age; $sex = $obj->sex; $comment = $obj->comment; echo "Processing record: " . $firstName . " " . $lastName . "<br>"; if ($stmt->execute()) { echo "New record created successfully<br>"; } else { echo "Error: " . $stmt->error . "<br>"; } } $stmt->close(); $conn->close(); } else { echo "Invalid JSON format: expected an array<br>"; } ?>
三、调试小技巧
- 直接访问PHP脚本的URL,确认能输出
PHP script started,验证服务器配置正常。 - 发送请求后查看PHP页面的输出,确认
Received input是否显示了你发送的JSON数据。 - 查看Android端Logcat的日志,确认响应码和数据发送的流程是否正常。
内容的提问来源于stack exchange,提问作者Yirga

