API返回404时Retrofit响应为null的问题排查
Retrofit 2调用返回404的API时响应解析失败的原因
问题场景
某API在数据库无对应数据时返回404状态码,同时返回结构化的JSON响应;使用Retrofit 2调用该API时,404情况下Retrofit返回null响应,无法解析实际返回的内容,但将API响应码改为200时,Retrofit就能正常解析响应。
相关代码
Barcode.activity代码
LnkBarcodeBaptizeCheckModel lnkModel = new LnkBarcodeBaptizeCheckModel(); List<String> bap_barcodes = new ArrayList<String>(); bap_barcodes.add(barcode); lnkModel.bap_barcodes = bap_barcodes; Call<LnkBarcodeBaptizeCheckResponseModel> lnkCall = apiInterface.CheckLnkBarcodeBaptizeTable(lnkModel); LnkBarcodeBaptizeCheckResponseModel lnkResponse = new MainAynscTask<LnkBarcodeBaptizeCheckResponseModel>().execute(lnkCall).get();
Retrofit Client代码
private static Retrofit retrofit = null; public static Retrofit getClient() { HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build(); Gson gson = new GsonBuilder().create(); retrofit = new Retrofit.Builder() .baseUrl("http://localserver/IndustrialApplicationsAPI/api/") .addConverterFactory(GsonConverterFactory.create(gson)) .client(client) .build(); return retrofit; }
API接口定义
@POST("CuringPhase/CheckLnkBarcodeBaptizeTable") Call<LnkBarcodeBaptizeCheckResponseModel> CheckLnkBarcodeBaptizeTable(@Body LnkBarcodeBaptizeCheckModel trcModel);
AsyncTask调用代码
public class MainAynscTask<T> extends AsyncTask<Call<T>, Void, T> { @Override protected T doInBackground(Call<T>... call) { T responseModel = null; try { responseModel = call[0].execute().body(); } catch (IOException e) { System.out.println("Call error: " + e.getLocalizedMessage()); } return responseModel; } @Override protected void onPostExecute(T result) { super.onPostExecute(result); //how i will pass this result where i called this task? }
API返回的404响应内容
{ "responseCode": 404, "data": [], "error": { "errorCode": 404, "errorDesc": "Not found!" } }
问题原因
- Retrofit 2的默认逻辑是:仅当HTTP响应状态码属于2xx成功范围时,才会调用配置的转换器(此处为GsonConverter)解析响应体,并通过
Response.body()返回解析后的对象。 - 当响应状态码是404这类4xx客户端错误码时,Retrofit会将其判定为请求错误,此时
Response.body()会返回null,实际的响应内容需要通过Response.errorBody()获取。 - 你的
MainAynscTask代码仅调用了call[0].execute().body(),完全未处理错误响应的解析逻辑,因此404时无法拿到解析后的响应对象;而将状态码改为200后,符合Retrofit的成功判定规则,会正常解析body内容,因此能得到有效结果。
内容的提问来源于stack exchange,提问作者erdogann
相关产品推荐
相关产品推荐

