Android中HTTP POST请求获JSON响应及Volley返回null问题排查
问题描述
我尝试向Web服务发起HTTP登录POST请求,按如下方式配置JsonObjectRequest,但调试时发现响应JSON对象为null(预期应返回JSON对象)。相关代码如下:
public UserData initLogin(Creds cr) { StringBuilder finalURL = new StringBuilder("https://"); finalURL.append(credentials.getUrl()); finalURL.append("/s1services"); Response.Listener<JSONObject> r1 = new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { res = response.toString(); us = gson.fromJson(String.valueOf(response), UserData.class); } }; JsonObjectRequest req = new JsonObjectRequest(Request.Method.POST, finalURL.toString(), cr.serObj(), r1, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { } }); return us; }
另外说明:Credentials类包含URL属性及getUrl()方法。请问是否需要将该请求加入请求队列?
回答
当然需要!这是你当前代码最核心的问题之一——Volley的所有请求都必须添加到RequestQueue中才会被执行,你现在只是创建了JsonObjectRequest实例,但没有把它交给Volley的请求队列去调度,所以这个请求根本没有发出去,自然得不到响应,us也一直是null。
除了这个核心问题,还有几个需要注意的点:
- 异步请求的返回时机问题:你的方法直接返回
us,但Volley请求是异步执行的,onResponse回调会在请求完成后才被调用,这时候方法早就已经返回了,所以即使你加入了请求队列,这个返回值也会是null。你需要改用回调接口或者LiveData这类工具来传递异步结果,而不是直接同步返回。 - 错误监听未处理:你的
ErrorListener是空实现,这样如果请求出现错误(比如网络问题、服务器错误),你完全看不到任何报错信息,建议在这里添加日志输出,比如Log.e("LoginError", error.toString(), error),方便排查问题。 - URL拼接可以简化:可以直接用字符串拼接简化URL构建,比如
String finalURL = "https://" + credentials.getUrl() + "/s1services";,代码会更简洁。
修正后的代码示例(假设你已初始化全局RequestQueue):
// 全局RequestQueue实例,建议在Application类中初始化 private RequestQueue requestQueue; public void initLogin(Creds cr, LoginCallback callback) { String finalURL = "https://" + credentials.getUrl() + "/s1services"; Response.Listener<JSONObject> successListener = new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { UserData userData = gson.fromJson(response.toString(), UserData.class); callback.onSuccess(userData); } }; Response.ErrorListener errorListener = new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e("LoginRequest", "登录请求失败", error); callback.onError(error); } }; JsonObjectRequest loginRequest = new JsonObjectRequest(Request.Method.POST, finalURL, cr.serObj(), successListener, errorListener); // 关键步骤:将请求加入队列执行 requestQueue.add(loginRequest); } // 定义回调接口传递异步结果 public interface LoginCallback { void onSuccess(UserData userData); void onError(VolleyError error); }
这样修改后,请求会被正常发送,你也能通过回调获取到登录结果,同时可以捕获请求中的错误信息。
内容的提问来源于stack exchange,提问作者xristos milios
相关产品推荐
相关产品推荐

