Java 使用改进型2转换器转换错误响应阵列
每当我得到错误时,错误主体如下所示:Java 使用改进型2转换器转换错误响应阵列,java,android,gson,retrofit2,Java,Android,Gson,Retrofit2,每当我得到错误时,错误主体如下所示: [ { "errorCode": 10001, "resource": null, "resourceId": null, "field": null, "parameter": null, "header": null, "allowedValues": null, "maxLength": null, "minLength": null } ] 错误主体是一个数组。我对许多API方法的成功有不同的看法,但错误数组
[
{
"errorCode": 10001,
"resource": null,
"resourceId": null,
"field": null,
"parameter": null,
"header": null,
"allowedValues": null,
"maxLength": null,
"minLength": null
}
]
错误主体是一个数组。我对许多API方法的成功有不同的看法,但错误数组响应是标准化的。我试过做很多事情
- 使用泛型类型成功响应和错误响应数组生成包装类,并为此生成反序列化器,但我无法从类型变量和参数化类进行反序列化
- 制作了一个ErrorDeserializer,但我不知道如何使用它进行错误响应
public class ResponseWrap<T> {
@Nullable
private final T response;
@Nullable
private final List<ErrorResponse> errorResponses;
public ResponseWrap(@Nullable T response, @Nullable List<ErrorResponse> errorResponses) {
this.response = response;
this.errorResponses = errorResponses;
}
}
错误反序列化程序:
public class ErrorDeserializer implements JsonDeserializer<ArrayList<ErrorResponse>> {
@Override
public ArrayList<ErrorResponse> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) {
Gson gson = new Gson();
Type listType = new TypeToken<ArrayList<ErrorResponse>>(){}.getType();
ArrayList<ErrorResponse> list = new Gson().fromJson(json, listType);
final JsonArray jsonArray = json.getAsJsonArray();
for (int i = 0; i < jsonArray.size(); i++) {
ErrorResponse error = new ErrorResponse();
JsonObject jsonObject = jsonArray.get(i).getAsJsonObject();
error.setErrorCode(jsonObject.get("errorCode").getAsInt());
error.setResource(jsonObject.get("resource").getAsString());
error.setResourceId(jsonObject.get("resourceId").getAsString());
error.setField(jsonObject.get("field").getAsString());
error.setParameter(jsonObject.get("parameter").getAsString());
error.setHeader(jsonObject.get("header").getAsString());
error.setAllowedValues(jsonObject.get("allowedValues").getAsString());
error.setMaxLength(jsonObject.get("maxLength").getAsInt());
error.setMinLength(jsonObject.get("minLength").getAsInt());
list.add(error);
}
return list;
}
}
公共类ErrorDeserializer实现JsonDeserializer{
@凌驾
公共ArrayList反序列化(JsonElement json,类型typeOfT,JsonDeserializationContext){
Gson Gson=新的Gson();
类型listType=newTypeToken(){}.getType();
ArrayList=new Gson().fromJson(json,listType);
final JsonArray JsonArray=json.getAsJsonArray();
for(int i=0;i
响应换行反序列化程序-不工作,2个错误:
- List error=new Gson().fromJson(jsonObject.getAsJsonObject(“error”),ArrayList.class);//无法从参数化类中选择
- T success=new Gson().fromJson(jsonObject,T.class);//无法从类型变量中选择
public class ResponseWrapDeserializer<T> implements JsonDeserializer<ResponseWrap<T>> { @Override public ResponseWrap<T> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { // Get JsonObject final JsonObject jsonObject = json.getAsJsonObject(); if (jsonObject.has("error")) { Gson gson = new GsonBuilder() .registerTypeAdapter(typeOfT, new ErrorDeserializer()) .setDateFormat("yyyy-MM-dd'T'HH:mm:ss") .create(); List<ErrorResponse> error = new Gson().fromJson(jsonObject.getAsJsonObject("error"), ArrayList<ErrorResponse>.class); return new ResponseWrap<T>(null, error); } else { T success = new Gson().fromJson(jsonObject, T.class); return new ResponseWrap<T>(success, null); } } }
公共类ResponseWrapDeserializer实现JsonDeserializer{ @凌驾 公共响应包装反序列化(JsonElement json,类型typeOfT,JsonDeserializationContext)引发JsonParseException{ //获取JsonObject final JsonObject JsonObject=json.getAsJsonObject(); if(jsonObject.has(“error”)){ Gson Gson=new GsonBuilder() .registerTypeAdapter(typeOfT,新的ErrorDeserializer()) .setDateFormat(“yyyy-MM-dd'T'HH:MM:ss”) .create(); List error=new Gson().fromJson(jsonObject.getAsJsonObject(“error”),ArrayList.class); 返回新的ResponseWrap(null,错误); }否则{ T success=new Gson().fromJson(jsonObject,T.class); 返回新的ResponseWrap(成功,空); } } }
@POST("Login")
Call<ResponseWrap<AccessTokenResponse>> Login(@Body LoginRequest request);
@POST(“登录”)
调用登录(@Body LoginRequest请求);
但是我不能,因为上面提到的原因
问题是:如何以通用方式处理使用Refught2的数组中的错误响应?您不能编写
T.class
——这在Java中是非法的。为了克服这一限制,您必须自己创建一个Type
实例,或者根据Gson提供的内容解析泛型类型参数。在第一种情况下,需要十几个JSON反序列化程序来绑定各种ResponseWrap
参数化;而在第二种情况下,您可以自己简单地解析实际的类型参数。在调用站点,您可以使用TypeToken
s——一种特殊的Gson机制,通过类型参数化定义类型参数。还请注意,您不必实例化内部Gson
实例:这可能会相对昂贵(尤其是在顺序上),并且不尊重当前反序列化程序绑定的Gson
配置-使用JsonDeserializationContext
,因为它可以为您提供所需的一切(下游类型适配器除外)
下面的JSON反序列化程序使用第二种方法,因为我觉得它更方便
final类ResponseWrapJsonDeserializer
实现JsonDeserializer{
//此反序列化程序不保存任何状态,因此我们可以隐藏其实例化详细信息
私有静态最终JsonDeserializer responseWrapJsonDeserializer=新responseWrapJsonDeserializer();
//TypeToken中的类型实例似乎是完全不可变的,并且可以作为值类型处理,因此我们可以使它们成为静态的最终类型,以便重用(这是安全的)
私有静态最终类型errorResponseListType=new-TypeToken(){
}.getType();
私有响应WrapJSondeSerializer(){
}
//只是欺骗调用站点:如果调用站点请求一个特殊类型的反序列化器,我们总是返回同一个实例(它总是同一个实例,然而,这正是Java泛型的工作方式)
静态JsonDeserializer getResponseWrapJsonDeserializer(){
@SuppressWarnings({“rawtypes”,“unchecked”})
最终JsonDeserializer转换=(JsonDeserializer)responseWrapJsonDeserializer;
回浇;
}
@凌驾
公共响应包装反序列化(最终JsonElement JsonElement、最终类型类型、最终JsonDeserialization
@POST("Login")
Call<ResponseWrap<AccessTokenResponse>> Login(@Body LoginRequest request);
{
"foo": [1, 2, 3]
}
[
{"errorCode": 10001},
{"errorCode": 10002}
]