Android调用PHP接口报org.json.JSONException:String无法转JSONObject
解决Android调用PHP接口时的JSON转换异常:org.json.JSONException
在开发教育用途的网页爬取应用时,Android端调用PHP接口获取JSON响应并展示,运行时抛出以下异常:
org.json.JSONException: Value Error of type java.lang.String cannot be converted to JSONObject
以下是相关代码及接口返回数据,结合这些信息排查问题并给出解决方案:
错误信息
org.json.JSONException: Value Error of type java.lang.String cannot be converted to JSONObject
Android端调用代码(MainActivity.java)
private void apicall() { RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext()); final StringRequest postRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() { @Override public void onResponse(String response) { try { JSONObject jsonObject1 = new JSONObject(response); if (jsonObject1.getString("active").equals("0")) { Toast.makeText(MainActivity.this, "Your account temporarily disabled by admin", Toast.LENGTH_SHORT).show(); preferences.edit().clear().apply(); Intent in = new Intent(getApplicationContext(), login.class); in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(in); finish(); } if (!jsonObject1.getString("session").equals(getSharedPreferences(constant.prefs, MODE_PRIVATE).getString("session", null))) { Toast.makeText(MainActivity.this, "Session expired ! Please login again", Toast.LENGTH_SHORT).show(); preferences.edit().clear().apply(); Intent in = new Intent(getApplicationContext(), login.class); in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(in); finish(); } balance.setText(jsonObject1.getString("wallet")); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { hometext.setText(Html.fromHtml(jsonObject1.getString("homeline"), Html.FROM_HTML_MODE_COMPACT)); } else { hometext.setText(Html.fromHtml(jsonObject1.getString("homeline"))); } ArrayList<String> name = new ArrayList<>(); ArrayList<String> result = new ArrayList<>(); JSONArray jsonArray = jsonObject1.getJSONArray("result"); for (int a = 0; a < jsonArray.length(); a++){ JSONObject jsonObject = jsonArray.getJSONObject(a); name.add(jsonObject.getString("market")); result.add(jsonObject.getString("result")); } adapter_result rc = new adapter_result(MainActivity.this,name,result); recyclerview.setLayoutManager(new GridLayoutManager(MainActivity.this, 2)); recyclerview.setAdapter(rc); rc.notifyDataSetChanged(); SharedPreferences.Editor editor = preferences.edit(); editor.putString("wallet", jsonObject1.getString("wallet")).apply(); editor.putString("homeline", jsonObject1.getString("homeline")).apply(); editor.putString("code", jsonObject1.getString("code")).apply(); is_gateway = jsonObject1.getString("gateway"); } catch (JSONException e) { e.printStackTrace(); Toast.makeText(MainActivity.this,e.toString(), Toast.LENGTH_SHORT).show(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { error.printStackTrace(); Toast.makeText(MainActivity.this, "Check your internet connection", Toast.LENGTH_SHORT).show(); } } ) { @Override protected Map<String, String> getParams() { Map<String, String> params = new HashMap<String, String>(); params.put("mobile", preferences.getString("mobile", null)); params.put("session",getSharedPreferences(constant.prefs, MODE_PRIVATE).getString("session", null)); return params; } }; postRequest.setRetryPolicy(new DefaultRetryPolicy(0, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); requestQueue.add(postRequest); }
PHP接口代码(home.php)
<?php include "../connection/config.php"; extract($_REQUEST); // if(rows(query("select sn from users where mobile='$mobile' and session ='$session'")) == 0){ // $data['msg'] = "You are not authrized to use this"; // $dd = query("select session,active from users where mobile='$mobile'"); // $d = fetch($dd); // $data['session'] = $d['session']; // $data['active'] = $d['active']; // echo json_encode($data); // return; // } require_once "../scrap/data/support/web_browser.php"; require_once "../scrap/data/support/tag_filter.php"; $htmloptions = TagFilter::GetHTMLOptions(); $url = "https://dpboss.mobi/"; $web = new WebBrowser(); $result = $web->Process($url); if (!$result["success"]) { echo "Error retrieving URL. " . $result["error"] . "\n"; exit(); } if ($result["response"]["code"] != 200) { echo "Error retrieving URL. Server returned: " . $result["response"]["code"] . " " . $result["response"]["meaning"] . "\n"; exit(); } $baseurl = $result["url"]; $html = TagFilter::Explode($result["body"], $htmloptions); $root = $html->Get(); $rows = $root->Find("div.satta-result h4"); $h5rows = $root->Find("div.satta-result h5"); foreach ($rows as $row) { $temp_h4[] = $row->GetInnerHTML(); } foreach ($h5rows as $row) { $temp_h5[] = $row->GetInnerHTML(); } $get = query("select * from gametime_new"); while($xc = fetch($get)) { $time = array_search($xc['market'], $temp_h4); $mrk['market'] = $xc['market']; $mrk['result'] = $temp_h5[$time]; $data['result'][] = $mrk; } $dd = query("select sn,wallet,active,session,code from users where mobile='$mobile'"); $d = fetch($dd); $nt = query("select homeline from content where sn='1'"); $n = fetch($nt); if($d['code'] == "0") { $code = $d['sn'].rand(100000,9999999); query("update users set code='$code' where mobile='$mobile'"); } else { $code = $d['code']; } if(rows(query("select sn from gateway_config where active='1'")) > 0){ $data['gateway'] = "1"; } else { $data['gateway'] = "0"; } $data['code'] = $code; $data['wallet'] = $d['wallet']; $data['active'] = $d['active']; $data['session'] = $d['session']; $data['homeline'] = $n['homeline']; echo json_encode($data);
接口返回的JSON示例
{"result":[{"market":"SRIDEVI","result":"249-54-356"},{"market":"TIME BAZAR","result":"568-98-279"},{"market":"MILAN DAY","result":"133-74-248"},{"market":"RAJDHANI DAY","result":"123-63-148"},{"market":"KALYAN","result":"266-44-130"},{"market":"SRIDEVI NIGHT","result":"588-11-489"},{"market":"NIGHT TIME BAZAR","result":"258-52-129"},{"market":"MILAN NIGHT","result":"568-98-440"},{"market":"KALYAN NIGHT","result":"447-57-188"},{"market":"RAJDHANI NIGHT","result":"458-76-790"},{"market":"MAIN BAZAR","result":"377-76-367"},{"market":"WORLI MUMBAI","result":"124-70-145"},{"market":"PUNA BAZAR","result":"350-89-379"},{"market":"MILAN MORNING","result":"123-63-148"}],"gateway":"1","code":null,"wallet":null,"active":null,"session":null,"homeline":"WELCOME TO BETPLAY"}
问题排查
- 异常根源:该异常说明Android端收到的响应不是合法JSON字符串,而是普通文本(比如"Error"开头的错误信息)。查看PHP代码,当爬取外部网站失败时,直接echo错误文本而非JSON,导致解析失败。
- 潜在隐患:
- 数据库查询用户数据时,若
$mobile不存在,$d为空,后续访问$d['code']会触发PHP警告,可能导致输出混乱。 - Android端使用
getString()获取可能为null的字段(比如code、wallet),会触发JSONException。
- 数据库查询用户数据时,若
解决方案
1. 统一PHP接口的JSON返回格式
无论成功还是失败,都返回JSON结构,替换原错误处理逻辑:
if (!$result["success"]) { $data['error'] = "Error retrieving URL. " . $result["error"]; echo json_encode($data); exit(); } if ($result["response"]["code"] != 200) { $data['error'] = "Error retrieving URL. Server returned: " . $result["response"]["code"] . " " . $result["response"]["meaning"]; echo json_encode($data); exit(); }
2. 处理PHP中数据库查询为空的情况
在获取用户数据后增加判断,避免后续报错:
$dd = query("select sn,wallet,active,session,code from users where mobile='$mobile'"); $d = fetch($dd); if(!$d){ $data['error'] = "用户不存在"; echo json_encode($data); exit(); }
3. Android端优化解析逻辑
- 增加响应日志打印,方便调试;
- 先检查响应是否包含错误字段;
- 使用
optString()替代getString(),避免null值触发异常:
@Override public void onResponse(String response) { try { Log.d("API_RESPONSE", response); // 打印响应日志 JSONObject jsonObject1 = new JSONObject(response); // 检查是否存在错误信息 if(jsonObject1.has("error")){ Toast.makeText(MainActivity.this, jsonObject1.getString("error"), Toast.LENGTH_SHORT).show(); return; } // 替换getString为optString,避免null值异常 if (jsonObject1.optString("active", "1").equals("0")) { // 原有逻辑... } String storedSession = getSharedPreferences(constant.prefs, MODE_PRIVATE).getString("session", null); if (!jsonObject1.optString("session", "").equals(storedSession) && storedSession != null) { // 原有逻辑... } balance.setText(jsonObject1.optString("wallet", "")); // 其他字段同样改用optString SharedPreferences.Editor editor = preferences.edit(); editor.putString("wallet", jsonObject1.optString("wallet", "")).apply(); editor.putString("code", jsonObject1.optString("code", "")).apply(); is_gateway = jsonObject1.optString("gateway", "0"); // 原有列表解析逻辑... } catch (JSONException e) { e.printStackTrace(); Toast.makeText(MainActivity.this,"接口返回数据格式错误", Toast.LENGTH_SHORT).show(); } }
内容的提问来源于stack exchange,提问作者Nilesh Singh Dahiya
相关产品推荐
相关产品推荐

