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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:55:03