如何使用Volley发送JSONArray参数并接收JSONObject响应,解决解析报错
问题根因
你遇到的报错由两个配置不匹配共同导致:
- 你使用的
JsonArrayRequest默认要求接口返回JSONArray类型的响应,但你的接口实际返回JSONObject,响应类型不匹配导致解析失败 - 你覆写的
getBodyContentType为表单格式application/x-www-form-urlencoded,但你需要提交的是JSONArray类型的请求参数,请求体格式不匹配会导致接口无法正常接收参数,返回空响应,触发End of input at character 0报错
解决方案
Volley支持自定义请求类适配你的场景,完全可以实现「发送JSONArray作为请求参数,接收JSONObject作为响应」的需求,实现步骤如下:
1. 自定义请求类
import com.android.volley.AuthFailureError; import com.android.volley.NetworkResponse; import com.android.volley.Request; import com.android.volley.Response; import com.android.volley.toolbox.HttpHeaderParser; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; public class JsonArrayPostJsonResponseRequest extends Request<JSONObject> { private final Response.Listener<JSONObject> successListener; private final JSONArray requestParams; public JsonArrayPostJsonResponseRequest(int method, String url, JSONArray requestParams, Response.Listener<JSONObject> successListener, Response.ErrorListener errorListener) { super(method, url, errorListener); this.successListener = successListener; this.requestParams = requestParams; } @Override public String getBodyContentType() { // 声明请求体为JSON格式 return "application/json; charset=utf-8"; } @Override public byte[] getBody() throws AuthFailureError { // 把请求参数JSONArray转为字节流提交 return requestParams.toString().getBytes(StandardCharsets.UTF_8); } @Override protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) { try { String responseContent = new String(response.data, HttpHeaderParser.parseCharset(response.headers, "utf-8")); // 直接把响应解析为JSONObject return Response.success(new JSONObject(responseContent), HttpHeaderParser.parseCacheHeaders(response)); } catch (UnsupportedEncodingException | JSONException e) { // 兼容空响应的场景,如果确认接口不会返回空可以去掉这段判断 if (response.data.length == 0) { return Response.success(new JSONObject(), HttpHeaderParser.parseCacheHeaders(response)); } return Response.error(new ParseError(e)); } } @Override protected void deliverResponse(JSONObject response) { successListener.onResponse(response); } }
2. 调用自定义请求类替换原有实现
// 替换为你实际的请求参数JSONArray JSONArray params = 你的业务参数数组; JsonArrayPostJsonResponseRequest volleyRequest = new JsonArrayPostJsonResponseRequest( Request.Method.POST, 你的接口URL, params, response -> { // 这里直接拿到接口返回的JSONObject,可直接使用 Log.d("TAG", "请求成功,响应内容:"+response); }, error -> { Log.e("TAG", "请求失败:", error); } ); VolleySingleton.getInstance(context).addToRequestQueue(volleyRequest);
特殊场景适配
如果你的接口确实要求请求参数用表单格式提交,不需要自定义请求类,直接把JSONArray作为某个表单字段的取值,用JsonObjectRequest提交即可,JsonObjectRequest本身支持接收JSONObject类型的响应。
内容的提问来源于stack exchange,提问作者Ammar Ahsan
相关产品推荐
相关产品推荐

