Moshi 无法使用泛型为 class 创建转换器
Moshi Unable to create converter for class with generic
我的一些服务器成功响应是:
{
"error": null,
"data": null
}
我的模型是:
public class BaseResponse<E > {
@Json(name = "error")
public ErrorModel error;
@Json(name = "data")
public E data;
}
如果我的端点是
@POST("user")
Call<BaseResponse<String>> createUser(@Body Credentials credentials);
这行得通,但 String 类型没有用,因为数据将始终为 null。但如果我做到了:
@POST("user")
Call<BaseResponse> createUser(@Body Credentials credentials);
我在
撞车了
Call<BaseResponse> call = apiService.createUser(creds);
完整日志:
java.lang.IllegalArgumentException: Unable to create converter for
class common.model.responses.BaseResponse for method MyEndpoints.createUser
...
Caused by: java.lang.IllegalArgumentException: Expected a Class, ParameterizedType,
or GenericArrayType, but <null> is of type null
at com.squareup.moshi.Types.getRawType(Types.java:167)
at com.squareup.moshi.ClassJsonAdapter.createFieldBindings(ClassJsonAdapter.java:83)
at com.squareup.moshi.ClassJsonAdapter.create(ClassJsonAdapter.java:75)
at com.squareup.moshi.Moshi.adapter(Moshi.java:100)
at com.squareup.moshi.ClassJsonAdapter.createFieldBindings(ClassJsonAdapter.java:91)
at com.squareup.moshi.ClassJsonAdapter.create(ClassJsonAdapter.java:75)
at com.squareup.moshi.Moshi.adapter(Moshi.java:100)
at retrofit2.converter.moshi.MoshiConverterFactory.responseBodyConverter(MoshiConverterFactory.java:91)
at retrofit2.Retrofit.nextResponseBodyConverter(Retrofit.java:330)
at retrofit2.Retrofit.responseBodyConverter(Retrofit.java:313)
at retrofit2.ServiceMethod$Builder.createResponseConverter(ServiceMethod.java:736)
...
出现此特定错误是因为无法知道 E
字段的类型,因为它未在原始类型用法中指定。
由于您知道此字段将始终为空,因此最好的解决方案是使用不同的类型(缺少该字段)来阐明这一点。
如果你真的不能使用不同的类型,你可以使用 Void
作为通用类型参数。不过,您需要在 Moshi 实例上注册一个 JsonAdapter 才能反序列化 Void 字段:new Moshi.Builder().add(VOID_JSON_ADAPTER).build()
static final Object VOID_JSON_ADAPTER = new Object() {
@FromJson Void fromJson(JsonReader reader) throws IOException {
return reader.nextNull();
}
@ToJson void toJson(JsonWriter writer, Void v) throws IOException {
writer.nullValue();
}
};
但是,使用不同的类型最有意义。
我的一些服务器成功响应是:
{ "error": null, "data": null }
我的模型是:
public class BaseResponse<E > {
@Json(name = "error")
public ErrorModel error;
@Json(name = "data")
public E data;
}
如果我的端点是
@POST("user")
Call<BaseResponse<String>> createUser(@Body Credentials credentials);
这行得通,但 String 类型没有用,因为数据将始终为 null。但如果我做到了:
@POST("user")
Call<BaseResponse> createUser(@Body Credentials credentials);
我在
撞车了Call<BaseResponse> call = apiService.createUser(creds);
完整日志:
java.lang.IllegalArgumentException: Unable to create converter for
class common.model.responses.BaseResponse for method MyEndpoints.createUser
...
Caused by: java.lang.IllegalArgumentException: Expected a Class, ParameterizedType,
or GenericArrayType, but <null> is of type null
at com.squareup.moshi.Types.getRawType(Types.java:167)
at com.squareup.moshi.ClassJsonAdapter.createFieldBindings(ClassJsonAdapter.java:83)
at com.squareup.moshi.ClassJsonAdapter.create(ClassJsonAdapter.java:75)
at com.squareup.moshi.Moshi.adapter(Moshi.java:100)
at com.squareup.moshi.ClassJsonAdapter.createFieldBindings(ClassJsonAdapter.java:91)
at com.squareup.moshi.ClassJsonAdapter.create(ClassJsonAdapter.java:75)
at com.squareup.moshi.Moshi.adapter(Moshi.java:100)
at retrofit2.converter.moshi.MoshiConverterFactory.responseBodyConverter(MoshiConverterFactory.java:91)
at retrofit2.Retrofit.nextResponseBodyConverter(Retrofit.java:330)
at retrofit2.Retrofit.responseBodyConverter(Retrofit.java:313)
at retrofit2.ServiceMethod$Builder.createResponseConverter(ServiceMethod.java:736)
...
出现此特定错误是因为无法知道 E
字段的类型,因为它未在原始类型用法中指定。
由于您知道此字段将始终为空,因此最好的解决方案是使用不同的类型(缺少该字段)来阐明这一点。
如果你真的不能使用不同的类型,你可以使用 Void
作为通用类型参数。不过,您需要在 Moshi 实例上注册一个 JsonAdapter 才能反序列化 Void 字段:new Moshi.Builder().add(VOID_JSON_ADAPTER).build()
static final Object VOID_JSON_ADAPTER = new Object() {
@FromJson Void fromJson(JsonReader reader) throws IOException {
return reader.nextNull();
}
@ToJson void toJson(JsonWriter writer, Void v) throws IOException {
writer.nullValue();
}
};
但是,使用不同的类型最有意义。