You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:58:11