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

Android Volley JsonObjectRequest如何处理PHP返回的字符串响应?

解决Volley JsonObjectRequest接收字符串响应触发onErrorResponse的问题

这个问题我之前也碰到过——Volley的JsonObjectRequest会严格校验响应是否为合法JSON,哪怕后端返回200状态码,但响应是纯字符串(比如"OK"),它也会因为解析失败触发onErrorResponse,而不是进入预期的onResponse。下面给你两种可行的解决方案:

方案一:临时快速处理(在错误回调中提取字符串)

既然你已经在onErrorResponse里捕获到了200状态码的情况,直接在这里处理响应字符串就可以快速解决问题:

@Override
public void onErrorResponse(VolleyError error) {
    Log.e("error", "error--->" + error.toString());
    NetworkResponse response = error.networkResponse;
    Log.e("statusCode","statusCode--->"+response.statusCode);
    String json = null;
    if (response != null && response.data != null) {
        switch (response.statusCode) {
            // 保留其他状态码的处理逻辑
            case 400:
                break;
            case 401:
                json = new String(response.data);
                break;
            case 502:
                json = new String(response.data);
                break;
            case 200:
                json = new String(response.data);
                // 这里直接处理字符串响应,比如判断是否是"OK"
                if ("OK".trim().equals(json)) {
                    // 执行原本onResponse里的成功逻辑,比如提示用户操作完成
                    Toast.makeText(context, "操作成功", Toast.LENGTH_SHORT).show();
                }
                progress.dismiss();
                break;
        }
    }
}

这种方法不用改动太多现有代码,适合快速收尾,但缺点是成功逻辑分散在错误回调中,代码结构不够优雅。

方案二:自定义Request(优雅长期解决方案)

更规范的做法是自定义一个支持字符串响应的Request,替代JsonObjectRequest,这样就能正常进入onResponse处理字符串,同时还能兼容后端后续可能返回JSON的情况:

1. 编写CustomStringRequest类

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

public class CustomStringRequest extends Request<String> {
    private final Response.Listener<String> mListener;
    private byte[] mRequestBody;

    public CustomStringRequest(int method, String url, JSONObject jsonRequest,
                               Response.Listener<String> listener, Response.ErrorListener errorListener) {
        super(method, url, errorListener);
        mListener = listener;
        // 处理POST请求的JSON请求体
        if (jsonRequest != null) {
            try {
                mRequestBody = jsonRequest.toString().getBytes("utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        String parsedResponse;
        try {
            parsedResponse = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
        } catch (UnsupportedEncodingException e) {
            // 编码失败时直接用默认编码解析
            parsedResponse = new String(response.data);
        }
        return Response.success(parsedResponse, HttpHeaderParser.parseCacheHeaders(response));
    }

    @Override
    protected void deliverResponse(String response) {
        mListener.onResponse(response);
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        return headers;
    }

    @Override
    public byte[] getBody() {
        return mRequestBody;
    }
}

2. 使用CustomStringRequest替代JsonObjectRequest

修改你的ResponseTask方法:

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

    CustomStringRequest req = new CustomStringRequest(Request.Method.POST, "", main,
        new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                progress.dismiss();
                Log.e("response","response---&gt;"+response);
                // 这里可以灵活处理:如果后端有时返回JSON,有时返回字符串
                try {
                    // 尝试解析成JSON
                    JSONObject jsonResponse = new JSONObject(response);
                    // 处理JSON格式的响应逻辑
                } catch (JSONException e) {
                    // 解析失败,说明是纯字符串,比如"OK"
                    if ("OK".trim().equals(response)) {
                        // 处理字符串成功逻辑
                    }
                }
            }
        },
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("error", "error---&gt;" + error.toString());
                progress.dismiss();
            }
        });

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

问题根源解释

Volley的JsonObjectRequest继承自Request<JSONObject>,它的parseNetworkResponse方法会强制把响应体解析为JSONObject。如果后端返回的不是合法JSON(比如纯字符串"OK"),就会抛出ParseError,直接触发onErrorResponse,哪怕HTTP状态码是200。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 03:28:14