如何在Retrofit中用Java泛型解析带动态类的错误响应?
实现Retrofit错误解析方法的动态泛型返回
要让parseError支持返回任意泛型参数的BaseApiResponse<DATA, ERROR>,你需要把方法改造为泛型方法,同时解决Gson解析泛型类型时的类型擦除问题。具体修改如下:
修改后的parseError方法
import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import retrofit2.Response; public class CommonUtils { // 复用Gson实例,避免重复创建 private static final Gson GSON = new Gson(); public static <DATA, ERROR> BaseApiResponse<DATA, ERROR> parseError(Response<?> response, TypeToken<BaseApiResponse<DATA, ERROR>> typeToken) { try { // 通过传入的TypeToken获取泛型类型,避免类型擦除导致解析错误 return GSON.fromJson(response.errorBody().charStream(), typeToken.getType()); } catch (Exception e) { // 创建泛型化的错误响应,避免unchecked警告 BaseApiResponse<DATA, ERROR> errResponse = new BaseApiResponse<>(); errResponse.setMessage("Error unexpected in JSON!"); return errResponse; } } }
调用方式
调用时只需传入对应泛型的TypeToken匿名实现,即可得到指定泛型的BaseApiResponse:
// 解析登录错误 BaseApiResponse<LoginResponse, LoginErrorResponse> loginErr = CommonUtils.parseError( response, new TypeToken<BaseApiResponse<LoginResponse, LoginErrorResponse>>() {} ); // 解析注册错误 BaseApiResponse<RegisterResponse, RegisterErrorResponse> registerErr = CommonUtils.parseError( response, new TypeToken<BaseApiResponse<RegisterResponse, RegisterErrorResponse>>() {} );
关键说明
- 泛型方法声明:通过
<DATA, ERROR>声明方法的泛型参数,让方法可以适配任意类型的BaseApiResponse。 - TypeToken传递:由于Java泛型擦除机制,Gson无法直接获取运行时的泛型类型,因此需要通过
TypeToken的匿名内部类来保留泛型信息,确保解析出正确的对象类型。 - 泛型化错误响应:异常分支中创建
BaseApiResponse<DATA, ERROR>实例,避免编译器的unchecked警告,保证类型安全。
如果你觉得每次传递TypeToken略显繁琐,也可以进一步封装,比如为常用的BaseApiResponse类型提供重载方法,但上述方案是最通用的实现方式。
内容的提问来源于stack exchange,提问作者Coder Newbie
相关产品推荐
相关产品推荐

