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

Android Kotlin使用Volley向Magento REST API发送JSON请求时遭遇JSON解析错误的技术问询

解决Volley请求Magento REST API时的ParseError问题

咱们先拆解你遇到的错误:com.android.volley.ParseError: org.json.JSONException: Value [] of type org.json.JSONArray cannot be converted to JSONObject,核心原因非常明确:你用了Volley的JsonObjectRequest发送请求,但Magento API返回的响应是JSON数组([]格式),而不是单个JSON对象({}格式),Volley强行按JSONObject去解析数组,自然就抛出了转换错误。

再看你的代码,请求体部分其实完全符合Magento文档要求(只是变量名itemsArray起得有点误导人,实际是JSONObject,不过不影响功能),问题出在响应解析的类型匹配上。下面给你两个可行的解决方案:

方案一:改用JsonArrayRequest适配响应格式

既然API返回的是JSON数组,直接把请求类型换成JsonArrayRequest即可,不过要注意JsonArrayRequest默认期望请求体也是JSON数组,所以需要重写getBody方法传入我们的JSONObject请求体:

// 保持请求体构建逻辑不变,把变量名改得更清晰
val itemsObject = JSONObject()
itemsObject.put("sku", "10-1001")
itemsObject.put("qty", 5)
itemsObject.put("quote_id", "3")
val requestBody = JSONObject()
requestBody.put("cartItem", itemsObject)

// 替换为JsonArrayRequest
val jsonRequest = object : JsonArrayRequest(
    Request.Method.POST,
    url,
    null, // 这里传null,后续通过重写getBody传入请求体
    Response.Listener { response ->
        try {
            // 现在可以正常处理JSONArray类型的响应
            binding.txtStatus.text = response.toString()
        } catch (e: JSONException) {
            e.printStackTrace()
            binding.txtStatus.text = e.toString()
        }
    },
    Response.ErrorListener { error ->
        binding.txtStatus.text = error.toString()
    }) {
    @Throws(AuthFailureError::class)
    override fun getBodyContentType(): String {
        return "application/json"
    }

    override fun getHeaders(): Map<String, String> {
        val apiHeader = HashMap<String, String>()
        apiHeader["Authorization"] = "Bearer $cusToken"
        return apiHeader
    }

    // 重写getBody方法,传入我们构建的JSONObject请求体
    override fun getBody(): ByteArray {
        return requestBody.toString().toByteArray(Charsets.UTF_8)
    }
}

val queue = Volley.newRequestQueue(this@MainActivity)
queue.add(jsonRequest)

方案二:用StringRequest手动解析响应(更灵活)

如果不确定API后续会不会返回不同格式的响应,或者想自己控制解析逻辑,用StringRequest先拿到原始响应字符串,再手动判断解析会更稳妥:

// 请求体构建逻辑不变
val itemsObject = JSONObject()
itemsObject.put("sku", "10-1001")
itemsObject.put("qty", 5)
itemsObject.put("quote_id", "3")
val requestBody = JSONObject()
requestBody.put("cartItem", itemsObject)

val jsonRequest = object : StringRequest(
    Request.Method.POST,
    url,
    Response.Listener { response ->
        try {
            // 手动判断响应是数组还是对象
            if (response.trimStart().startsWith("[")) {
                val jsonArray = JSONArray(response)
                binding.txtStatus.text = "返回数组:$jsonArray"
            } else {
                val jsonObject = JSONObject(response)
                binding.txtStatus.text = "返回对象:$jsonObject"
            }
        } catch (e: JSONException) {
            e.printStackTrace()
            binding.txtStatus.text = "解析失败:${e.toString()}"
        }
    },
    Response.ErrorListener { error ->
        binding.txtStatus.text = error.toString()
    }) {
    @Throws(AuthFailureError::class)
    override fun getBodyContentType(): String {
        return "application/json"
    }

    override fun getHeaders(): Map<String, String> {
        val apiHeader = HashMap<String, String>()
        apiHeader["Authorization"] = "Bearer $cusToken"
        return apiHeader
    }

    override fun getBody(): ByteArray {
        return requestBody.toString().toByteArray(Charsets.UTF_8)
    }
}

val queue = Volley.newRequestQueue(this@MainActivity)
queue.add(jsonRequest)

最后小提醒:你可以先用Postman之类的工具测试这个API端点,确认响应格式,同时检查请求URL是否正确、token是否有效,这些基础问题也可能导致异常响应哦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 11:22:53