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

如何在Android Volley的JsonObjectRequest中获取PHP返回的字符串响应?

解决Volley JsonObjectRequest因后端返回字符串触发ParseError的问题

你遇到的这个问题很常见——JsonObjectRequest默认会强制将响应体解析为JSONObject,当后端返回纯字符串(比如"OK")时,JSON解析器会抛出异常,即使HTTP状态码是200,也会触发onErrorResponse而不是onResponse。下面给你两种可行的解决方案,以及一些实用建议:

方案一:改用StringRequest直接处理字符串响应

既然后端返回的是字符串,最直接的方式是换成StringRequest,这样你能在onResponse里拿到原始字符串,再灵活处理(比如判断是否是"OK",或者按需转JSON)。

修改后的代码示例:

public class SampleJsonObjTask { 
    public static ProgressDialog progress; 
    private static RequestQueue queue; 
    JSONObject main; 
    StringRequest req; 
    private MainActivity context; 
    private String prd,us,ver,fha,ve,ves,sz,cat,pa,h,t,en,pha,pur,dip; 

    public SampleJsonObjTask(MainActivity context, JSONObject main) { 
        progress = new ProgressDialog(context); 
        progress.setMessage("Loading..."); 
        progress.setCanceledOnTouchOutside(false); 
        progress.setCancelable(false); 
        progress.show(); 
        this.context = context; 
        this.main = main; 
        ResponseTask(); 
    } 

    private void ResponseTask() { 
        if (queue == null) { 
            queue = Volley.newRequestQueue(context); 
        } 

        req = new StringRequest(Request.Method.POST, "你的接口URL", 
            new Response.Listener<String>() { 
                @Override 
                public void onResponse(String response) { 
                    progress.dismiss(); 
                    Log.e("response","response--->"+response); 
                    // 处理字符串响应
                    String trimmedResp = response.trim();
                    if ("OK".equals(trimmedResp)) {
                        // 处理成功逻辑
                        Toast.makeText(context, "操作完成", Toast.LENGTH_SHORT).show();
                    } else {
                        // 如果需要转JSON,尝试解析
                        try {
                            JSONObject jsonResp = new JSONObject(trimmedResp);
                            // 处理JSON格式的响应
                        } catch (JSONException e) {
                            e.printStackTrace();
                            // 处理其他非JSON字符串场景
                        }
                    }
                } 
            }, 
            new Response.ErrorListener() { 
                @Override 
                public void onErrorResponse(VolleyError error) { 
                    progress.dismiss(); 
                    // 处理真正的错误(网络问题、非200状态码等)
                    Toast.makeText(context, "请求失败:" + error.getMessage(), Toast.LENGTH_SHORT).show();
                } 
            }) { 
            @Override 
            public Map<String, String> getHeaders() throws AuthFailureError { 
                Map<String, String> params = new HashMap<>(); 
                params.put("Content-Type", "application/json"); 
                return params; 
            } 

            @Override
            public byte[] getBody() throws AuthFailureError {
                // 将请求的JSONObject转为字节数组(StringRequest默认不处理JSON请求体)
                try {
                    return main.toString().getBytes("utf-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        }; 

        req.setRetryPolicy(new DefaultRetryPolicy(20 * 1000, 0, 1f)); 
        queue.add(req); 
    } 
}

方案二:自定义JsonObjectRequest兼容字符串响应

如果你更习惯JsonObjectRequest的回调结构,可以自定义一个请求类,重写parseNetworkResponse方法,当JSON解析失败时,把字符串包装成合法的JSONObject返回。

自定义请求类代码:

public class FlexibleJsonObjectRequest extends JsonObjectRequest {
    public FlexibleJsonObjectRequest(int method, String url, JSONObject jsonRequest,
                                     Response.Listener<JSONObject> listener,
                                     Response.ErrorListener errorListener) {
        super(method, url, jsonRequest, listener, errorListener);
    }

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            // 先尝试默认的JSON解析
            return super.parseNetworkResponse(response);
        } catch (ParseError parseError) {
            // 解析失败,包装字符串为JSONObject返回
            try {
                String responseString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
                JSONObject wrappedJson = new JSONObject();
                wrappedJson.put("raw_response", responseString.trim());
                return Response.success(wrappedJson, HttpHeaderParser.parseCacheHeaders(response));
            } catch (UnsupportedEncodingException | JSONException e) {
                // 仍无法处理则返回错误
                return Response.error(new ParseError(e));
            }
        }
    }
}

在你的任务类中使用这个自定义请求:

req = new FlexibleJsonObjectRequest(Request.Method.POST, "你的接口URL", main, 
    new Response.Listener<JSONObject>() { 
        @Override 
        public void onResponse(JSONObject response) { 
            progress.dismiss(); 
            try {
                // 先尝试获取包装后的字符串
                String rawResp = response.getString("raw_response");
                Log.e("response","response--->"+rawResp);
                if ("OK".equals(rawResp)) {
                    // 处理成功逻辑
                }
            } catch (JSONException e) {
                // 说明响应本身是合法JSON,直接处理
                Log.e("response","json response--->"+response.toString());
            }
        } 
    }, 
    new Response.ErrorListener() { 
        @Override 
        public void onErrorResponse(VolleyError error) { 
            progress.dismiss(); 
            // 区分解析错误和真实错误
            if (error instanceof ParseError) {
                Toast.makeText(context, "响应格式异常", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(context, "请求失败:" + error.getMessage(), Toast.LENGTH_SHORT).show();
            }
        } 
    }) { 
    @Override 
    public Map<String, String> getHeaders() throws AuthFailureError { 
        Map<String, String> params = new HashMap<>(); 
        params.put("Content-Type", "application/json"); 
        return params; 
    } 
};

额外建议

  1. 优先和后端沟通:最规范的解决方式是让后端统一返回JSON格式响应,比如把"OK"改成{"status": "OK"},这样能避免后续的解析问题,也符合RESTful接口规范。
  2. 错误精细化处理:在onErrorResponse里可以通过VolleyError的类型,区分是解析错误还是真实的网络/状态码错误,给用户更准确的提示。

内容的提问来源于stack exchange,提问作者karthik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:58:40