使用Volley发送JSON请求遇ParseError,如何修复该异常?
问题:Volley POST请求抛出ParseError,无法将String转为JSONObject
以下是我使用的Activity.java代码:
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, URL, null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { Log.d("volleytracker", response.toString()); try { String message = response.getString("message"); boolean successful = response.getBoolean("result"); String userId = response.getString("user_id"); if (successful) { //save userId on shared memory PrefManager prefManager = new PrefManager(context); prefManager.SaveUSerID(Integer.valueOf(userId)); // intent NextActivity Intent intent = new Intent(Register.this, VerificationPage.class); startActivity(intent); } else { status.setText(message); status.setTextColor(Color.parseColor("#FF0000")); } } catch (JSONException e) { Log.d("checkError", e.toString()); e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(Register.this, error.toString().trim(), Toast.LENGTH_SHORT).show(); Log.d("errorcheck", error.toString()); regBtn.setEnabled(true); } }) { public byte[] getBody() { JSONObject jsonParams = new JSONObject(); try { jsonParams.put("name", name); jsonParams.put("PhoneNumber", phone); jsonParams.put("deviceId", deviceId); //jsonParams.put("DeviceIP", getiP); //Log.d("jsonPara",jsonParams.toString()); } catch (JSONException e) { e.printStackTrace(); } return jsonParams.toString().getBytes(); } @Override public String getBodyContentType() { return "application/json"; } @Override public Map<String, String> getHeaders() throws AuthFailureError { Map<String, String> headers = new HashMap<>(); return headers; } }; RequestQueue requestQueue = Volley.newRequestQueue(Register.this); requestQueue.add(jsonObjectRequest);
运行代码时抛出错误:com.android.volley.ParseError: org.json.JSONException: Value Invalid of type java.lang.String cannot be converted to JSONObject
使用Postman测试该请求可正常工作,需要修复此问题。
解决方法
这个错误的核心原因是:服务器返回的不是合法的JSON格式字符串,而是普通文本(比如"Invalid"),但你用的JsonObjectRequest会强制将响应解析为JSONObject,因此解析失败。以下是具体的排查和修复步骤:
1. 先确认服务器返回的实际内容
在ErrorListener中添加代码,打印服务器返回的原始响应内容(因为Volley会把非JSON响应判定为错误):
@Override public void onErrorResponse(VolleyError error) { if (error.networkResponse != null && error.networkResponse.data != null) { String responseBody = new String(error.networkResponse.data, StandardCharsets.UTF_8); Log.d("errorResponse", "服务器返回内容:" + responseBody); } Toast.makeText(Register.this, error.toString().trim(), Toast.LENGTH_SHORT).show(); Log.d("errorcheck", error.toString()); regBtn.setEnabled(true); }
通过日志你能看到服务器到底返回了什么(比如"Invalid"),再对比Postman的请求,找出差异。
2. 检查请求体与请求头的差异
Postman请求正常但代码请求异常,大概率是两者的请求参数或请求头不一致:
- 检查字段名:比如代码中的
PhoneNumber是否和服务器要求的字段名一致(比如是否是小写开头的phoneNumber); - 检查参数值:确认
name、phone、deviceId变量是否为空、格式是否符合服务器要求(Postman是手动输入合法值,代码中可能变量未正确赋值); - 完善请求头:明确指定编码,避免字符集问题:
@Override public String getBodyContentType() { return "application/json; charset=utf-8"; }
3. 改用StringRequest兼容非JSON响应
如果服务器确实会在错误场景返回普通文本,建议改用StringRequest接收响应,再手动判断是JSON还是普通文本:
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() { @Override public void onResponse(String response) { Log.d("volleytracker", response); try { // 尝试解析为JSON JSONObject jsonResponse = new JSONObject(response); String message = jsonResponse.getString("message"); boolean successful = jsonResponse.getBoolean("result"); String userId = jsonResponse.getString("user_id"); if (successful) { PrefManager prefManager = new PrefManager(context); prefManager.SaveUSerID(Integer.valueOf(userId)); Intent intent = new Intent(Register.this, VerificationPage.class); startActivity(intent); } else { status.setText(message); status.setTextColor(Color.parseColor("#FF0000")); } } catch (JSONException e) { // 解析失败,处理普通文本响应 Log.d("nonJsonResponse", response); status.setText(response); status.setTextColor(Color.parseColor("#FF0000")); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { if (error.networkResponse != null && error.networkResponse.data != null) { String responseBody = new String(error.networkResponse.data, StandardCharsets.UTF_8); Log.d("errorResponse", responseBody); } Toast.makeText(Register.this, error.toString().trim(), Toast.LENGTH_SHORT).show(); Log.d("errorcheck", error.toString()); regBtn.setEnabled(true); } }) { @Override public byte[] getBody() throws AuthFailureError { JSONObject jsonParams = new JSONObject(); try { jsonParams.put("name", name); jsonParams.put("PhoneNumber", phone); jsonParams.put("deviceId", deviceId); } catch (JSONException e) { e.printStackTrace(); } return jsonParams.toString().getBytes(StandardCharsets.UTF_8); } @Override public String getBodyContentType() { return "application/json; charset=utf-8"; } }; RequestQueue requestQueue = Volley.newRequestQueue(Register.this); requestQueue.add(stringRequest);
4. 排查服务器端逻辑
确认服务器是否对请求参数有特殊校验,比如deviceId在代码中的值是否和Postman中不同,导致服务器返回"Invalid"的提示。
内容的提问来源于stack exchange,提问作者Thanusha
相关产品推荐
相关产品推荐

