Android Volley请求触发ServerError问题求助
问题描述
我跟着教程开发一款从服务器拉取JSON数据的基础Android App,但遇到了网络请求失败的问题:
- 无论在真机还是模拟器上,使用Retrofit或Volley发起请求时,代码都会直接进入
OnFailure回调,提示“获取数据失败”。 - 已排查设备网络连接正常,服务器地址在浏览器和Jsoup中能正常访问并返回JSON数据。
- 查看Logcat发现触发了
com.android.volley.ServerError,怀疑是数据解析时的空值问题导致。 - 代码采用的是他人已经验证过可行的版本,但在我这里无法正常运行,附上相关代码片段寻求帮助。
相关代码片段
Volley请求代码
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL, response -> { // 成功回调逻辑 }, error -> { Log.e("VolleyError", error.toString()); Toast.makeText(context, "获取数据失败", Toast.LENGTH_SHORT).show(); }) { @Override public Map<String, String> getHeaders() throws AuthFailureError { Map<String, String> headers = new HashMap<>(); headers.put("Content-Type", "application/json"); return headers; } }; RequestQueue queue = Volley.newRequestQueue(context); queue.add(stringRequest);
Retrofit接口与实体类
// 接口定义 public interface ApiService { @GET("api/data") Call<DataResponse> getData(); } // 数据实体类 public class DataResponse { private String name; private int id; // getter/setter方法 }
Retrofit请求代码
Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); ApiService service = retrofit.create(ApiService.class); Call<DataResponse> call = service.getData(); call.enqueue(new Callback<DataResponse>() { @Override public void onResponse(Call<DataResponse> call, Response<DataResponse> response) { if (response.isSuccessful()) { // 数据处理逻辑 } else { Toast.makeText(context, "获取数据失败", Toast.LENGTH_SHORT).show(); } } @Override public void onFailure(Call<DataResponse> call, Throwable t) { Log.e("RetrofitError", t.toString()); Toast.makeText(context, "获取数据失败", Toast.LENGTH_SHORT).show(); } });
排查与解决方案
先定位ServerError的具体原因
不要只看ServerError的表层提示,打印完整错误细节:- Volley中可以通过
error.networkResponse.statusCode获取HTTP状态码,通过new String(error.networkResponse.data)拿到服务器返回的错误内容; - Retrofit中在
onResponse的非成功分支里,用response.errorBody().string()打印错误响应体。
状态码能快速定位问题:404是请求地址错误,500是服务器内部异常,401是权限验证缺失等。
- Volley中可以通过
核对实体类与JSON结构的匹配度
空值相关的解析错误大概率是实体类与JSON字段不匹配:- 先打印服务器返回的原始JSON字符串,对比实体类字段:JSON中存在的字段,实体类必须有对应定义,或者用
@SerializedName("json_key_name")做键名映射(比如JSON是user_name,实体类字段是userName时必须加注解); - 给允许为空的字段加上
@Nullable注解,或设置默认值,避免Gson解析空值时抛出异常。
- 先打印服务器返回的原始JSON字符串,对比实体类字段:JSON中存在的字段,实体类必须有对应定义,或者用
检查请求头与请求地址的合法性
- GET请求无需设置
Content-Type: application/json头,多余的请求头可能被服务器拒绝,尝试去掉Volley中的getHeaders()重写方法; - 确认Retrofit的
baseUrl必须以/结尾,接口的@GET路径不能以/开头,否则会导致地址拼接错误(比如baseUrl是https://example.com/api/,接口应写@GET("data")而非@GET("/data"))。
- GET请求无需设置
处理明文网络访问限制
如果服务器使用HTTP而非HTTPS,需在AndroidManifest.xml的application标签中添加android:usesCleartextTraffic="true",否则Android 9及以上系统会禁止明文请求。验证JSON格式合法性
把服务器返回的JSON字符串复制到本地校验工具中,检查是否存在语法错误(比如遗漏逗号、引号不匹配),非法JSON会直接导致解析失败触发错误。
内容的提问来源于stack exchange,提问作者John B Gilbert
相关产品推荐
相关产品推荐

