Android处理PHP非JSON响应时java.lang.Integer转JSONObject异常
问题分析
你遇到的JSONException核心原因是服务器返回的响应格式不统一:
- 用户已存在时,返回JSON编码的对象(比如
{"user_details": [...]}) - 用户不存在时,返回普通字符串(
user inserted successfully或0)
而你的Android代码默认把所有响应都尝试转换成JSONObject,当收到非JSON格式的普通字符串时,自然会触发类型不匹配的异常——就像日志里显示的Value 1 of type java.lang.Integer cannot be converted to JSONObject(这里的"1"实际是服务器返回的0被解析时识别成了整数类型,本质是字符串不符合JSON格式)。
解决方案
优先推荐统一服务器端返回JSON格式,这是API开发的最佳实践,能彻底避免客户端解析异常,也让接口逻辑更清晰。
1. 修改PHP服务器端代码,统一返回JSON
修改Users控制器的create方法,让所有场景都返回标准JSON响应:
class Users extends CI_Controller { public function create(){ $data=$this->check_exist($this->input->post('user_id')); // 初始化统一响应结构 $response = [ 'status' => '', // 标识状态:exists/success/error 'message' => '', // 提示信息 'data' => [] // 存放用户数据(可选) ]; if($data=='0') { $this->load->model('UsersModel'); $msg = $this->UsersModel->create(); if ($msg==true) { $response['status'] = 'success'; $response['message'] = 'user inserted successfully'; } else { $response['status'] = 'error'; $response['message'] = 'Insert failed'; } } else{ $response['status'] = 'exists'; $response['message'] = 'User already exists'; $response['data']['user_details'] = $data; } // 设置正确的响应头,告诉客户端这是JSON格式 header('Content-Type: application/json'); echo json_encode($response); } public function check_exist($user_id) { $this->load->helper('url'); $this->load->model('UsersModel'); $data=$this->UsersModel->user_exist($user_id); return !empty($data) ? $data : '0'; } }
改动说明:
- 用统一的
$response数组封装所有返回结果,结构清晰,便于客户端解析 - 增加
Content-Type响应头,明确告知客户端返回内容类型 - 所有分支最终都通过
json_encode输出JSON,彻底统一格式
2. 修改Android端代码,适配统一JSON响应
现在服务器返回格式统一了,Android端可以稳定解析,修改后的代码如下:
try { final Database_Helper dg = new Database_Helper(getBaseContext()); ServerUrl obj = new ServerUrl(); HashMap postData = new HashMap(); postData.put("user_id", personId); postData.put("user_name", personName); postData.put("email", personEmail); postData.put("profile_picture", String.valueOf(personPhoto)); final PostResponseAsyncTask readTask = new PostResponseAsyncTask(UserLogin.this, postData, new AsyncResponse() { public void processFinish(String mStringArray) { Log.w("data", "Server response: " + mStringArray); try { JSONObject json = new JSONObject(mStringArray); String status = json.getString("status"); switch (status) { case "exists": // 用户已存在,读取服务器返回的用户详情存入SQLite JSONArray userDetailsArray = json.getJSONArray("user_details"); if (userDetailsArray.length() > 0) { JSONObject details = userDetailsArray.getJSONObject(0); dg.user_Putrecord(dg, details.getString("auth_id"), details.getString("full_name"), details.getString("email_id"), details.getString("profile_url")); Toast.makeText(UserLogin.this, "用户已存在,已同步数据", Toast.LENGTH_LONG).show(); } break; case "success": // 用户插入成功,将本地数据存入SQLite dg.user_Putrecord(dg, personId, personName, personEmail, String.valueOf(personPhoto)); Toast.makeText(UserLogin.this, json.getString("message"), Toast.LENGTH_LONG).show(); break; case "error": // 插入失败,提示错误信息 Toast.makeText(UserLogin.this, json.getString("message"), Toast.LENGTH_LONG).show(); break; } } catch (JSONException e) { e.printStackTrace(); Toast.makeText(UserLogin.this, "解析服务器响应失败", Toast.LENGTH_SHORT).show(); } } }); obj.url("Users","create"); readTask.execute(obj.domain_url); } catch (Exception ex) { Toast.makeText(UserLogin.this, ex.getMessage(), Toast.LENGTH_SHORT).show(); }
改动说明:
- 先解析统一的
status字段,根据不同状态分支处理业务逻辑 - 每种状态对应明确的操作:同步已有用户数据、存储新用户数据、提示插入失败
- 异常处理更友好,给用户明确的错误提示
备选方案:不修改服务器,Android端兼容两种格式
如果暂时无法修改服务器代码,可以在Android端先判断响应是否为JSON格式,再分别处理:
public void processFinish(String mStringArray) { Log.w("data", "Server response: " + mStringArray); try { // 先尝试解析为JSON对象 JSONObject json = new JSONObject(mStringArray); JSONArray jsonscoresarray = json.getJSONArray("user_details"); if (jsonscoresarray.length() > 0) { JSONObject details = jsonscoresarray.getJSONObject(0); dg.user_Putrecord(dg, details.getString("auth_id"), details.getString("full_name"), details.getString("email_id"), details.getString("profile_url")); Toast.makeText(UserLogin.this, "用户已存在", Toast.LENGTH_LONG).show(); } } catch (JSONException e) { // 解析失败,说明是普通字符串 if (mStringArray.equals("user inserted successfully")) { dg.user_Putrecord(dg, personId, personName, personEmail, String.valueOf(personPhoto)); Toast.makeText(UserLogin.this, mStringArray, Toast.LENGTH_LONG).show(); } else if (mStringArray.equals("0")) { Toast.makeText(UserLogin.this, "插入失败", Toast.LENGTH_LONG).show(); } else { Toast.makeText(UserLogin.this, "未知响应:" + mStringArray, Toast.LENGTH_LONG).show(); } e.printStackTrace(); } }
注意:
这种方案依赖服务器返回的固定字符串,一旦服务器修改返回内容,客户端就会失效,因此仅作为临时过渡方案,还是推荐统一JSON格式的方案更可靠。
内容的提问来源于stack exchange,提问作者aamer
相关产品推荐
相关产品推荐

