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

如何将Volley的StringRequest转为JsonArrayRequest?解析错误排查

问题描述

我想把Volley中的StringRequest改成JsonArrayRequest,以便将返回的JSON数组拆分为不同变量。

原StringRequest代码:

RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());

StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
        Log.d("res", response);
        if (response.equals("failure")) {
            Toast.makeText(MainActivity.this, "Ungültige Anmeldedaten", Toast.LENGTH_SHORT).show();
        } else {
            TV.setText(response);
            //ID = Integer.parseInt(response);
            //switchToMain();
        }
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        Toast.makeText(MainActivity.this, error.toString().trim(), Toast.LENGTH_SHORT).show();
    }
}){
    @Override
    protected Map<String, String> getParams() throws AuthFailureError {
        Map<String, String> data = new HashMap<>();
        data.put("email", email);
        data.put("password", password);
        return data;
    }
};

requestQueue.add(stringRequest);

接口返回的JSON数组:

[{"id":"6","Username":"a","Email":"a","Password":"0cc175b9c0f1b6a831c399e269772661","Status":"Online"}]

改成JsonArrayRequest后报错,修改后的代码:

RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());

JsonArrayRequest queue = new JsonArrayRequest(Request.Method.POST,URL,null,new Response.Listener<JSONArray>(){
    @Override
    public void onResponse(JSONArray response) {

        if (response.equals("null")) {
            Toast.makeText(MainActivity.this, "Ungültige Anmeldedaten", Toast.LENGTH_SHORT).show();
        } else {

            //ID = Integer.parseInt(response);
            //switchToMain();
        }
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        Toast.makeText(MainActivity.this, error.toString().trim(), Toast.LENGTH_SHORT).show();
    }
}){
    @Override
    protected Map<String, String> getParams() throws AuthFailureError {
        Map<String, String> data = new HashMap<>();
        data.put("email", email);
        data.put("password", password);
        return data;
    }
};

requestQueue.add(queue);

错误信息:

com.android.volley.ParseError: org.json.JSONException: End of input at character 0 of


问题原因及解决方案

核心问题1:JsonArrayRequest默认不兼容表单参数提交

JsonArrayRequest的构造方法默认将请求头设为application/json,但你通过getParams()传递的是表单格式参数(application/x-www-form-urlencoded),服务器无法正确解析参数,返回空响应,触发JSON解析错误。

核心问题2:错误的空判断逻辑

response.equals("null")完全不成立——JSONArray对象和字符串"null"属于不同类型,永远不会相等,需要根据服务器返回逻辑调整判断方式。

修复后的完整代码

RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());

JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.POST, URL, null,
        new Response.Listener<JSONArray>() {
            @Override
            public void onResponse(JSONArray response) {
                // 处理成功返回的JSON数组
                if (response.length() == 0) {
                    // 无数据时提示登录失败
                    Toast.makeText(MainActivity.this, "Ungültige Anmeldedaten", Toast.LENGTH_SHORT).show();
                } else {
                    try {
                        // 取出数组中的第一个用户对象
                        JSONObject userObj = response.getJSONObject(0);
                        // 拆分出所需变量
                        String id = userObj.getString("id");
                        String username = userObj.getString("Username");
                        String email = userObj.getString("Email");
                        String status = userObj.getString("Status");

                        // 执行后续业务逻辑
                        // ID = Integer.parseInt(id);
                        // TV.setText(username);
                        // switchToMain();
                    } catch (JSONException e) {
                        e.printStackTrace();
                        Toast.makeText(MainActivity.this, "数据解析失败", Toast.LENGTH_SHORT).show();
                    }
                }
            }
        },
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                // 优化错误提示
                String errorMsg;
                if (error instanceof NetworkError) {
                    errorMsg = "网络连接失败";
                } else if (error instanceof ParseError) {
                    errorMsg = "数据解析错误";
                } else {
                    errorMsg = error.toString().trim();
                }
                Toast.makeText(MainActivity.this, errorMsg, Toast.LENGTH_SHORT).show();
            }
        }) {
    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        // 设置适配表单参数的请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/x-www-form-urlencoded");
        return headers;
    }

    @Override
    protected Map<String, String> getParams() throws AuthFailureError {
        Map<String, String> data = new HashMap<>();
        data.put("email", email);
        data.put("password", password);
        return data;
    }
};

requestQueue.add(jsonArrayRequest);

额外说明

如果服务器在登录失败时返回的是字符串"failure"(和原StringRequest逻辑一致),JsonArrayRequest会直接触发解析错误,因为字符串不是合法的JSON数组。这种情况有两种处理方式:

  • 和后端协商,统一返回JSON格式(比如失败时返回[]或{"code":-1,"msg":"登录失败"})
  • 继续使用StringRequest接收响应,先判断是否为"failure",再将合法的JSON字符串手动解析为JSONArray

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 16:24:13