我正在Kotlin中使用Retrofit2 + Moshi连接到服务器。
所有响应均包装有 result 属性。我创建了如下的通用数据类
@JsonClass(generateAdapter = true)
data class CommonResponse<T>(val result: T?)
例如,如果result属性不为空,则可以正常工作
{
"result": {
"bar": 1
}
}
具有数据类Foo并将泛型与Foo一起使用
data class Foo(val bar: Int)
interface {
@Path("/foo")
fun getFoo(): CommonResponse<Foo>
}
但是,如果 result 属性为空,则如下所示:
{
"result": {}
}
由于bar不能为null,我得到了JsonDataException。
对于result属性为空的情况,是否可以将其视为null?
到目前为止,我所做的就是捕获JsonDataException异常并为这些情况返回null,但是由于没有数据的结果是有效的响应,因此我对这种解决方案不满意。另外,我将无法在没有结果的响应或无效的响应之间进行区分。
有什么主意吗?
注意:我无法修改服务器响应。
答案 0 :(得分:0)
对于result属性为空的情况,是否可以将其视为null?
是的,您需要使属性栏可为空,因为Int?
例外,并为该属性添加默认值,这样,如果不存在该属性,则可以将其设置为null。因此,将data class Foo(val bar: Int)
更改为data class Foo(val bar: Int? = null)
这会将以下JSON的bar设置为null:
{
"result": {
"bar": null
}
}
...和
{
"result": {}
}
答案 1 :(得分:0)
如果JSON为空,要将结果设置为null,则需要为CommonResponse创建自己的自定义适配器。因此,首先您不需要为CommonResponse生成适配器:
data class CommonResponse<T>(val result: T?)
data class Foo(val bar: Int)
...然后您需要为Foo类型的CommonResponse创建自定义适配器:
class CommonResponseAdapterFoo {
@FromJson
fun fromJson(reader: JsonReader): CommonResponse<Foo>{
var fooObj: Foo? = null
while (reader.hasNext()) {
reader.beginObject()
if (reader.nextName() == "result") {
reader.beginObject()
if (reader.hasNext()) {
if (reader.nextName() == "bar") {
val barValue = reader.nextInt()
fooObj = Foo(barValue)
}
}
reader.endObject()
}
reader.endObject()
}
return CommonResponse(fooObj)
}
}
...然后您需要将此自定义适配器添加到您的moshi实例:
val moshi = Moshi.Builder().add(CommonResponseAdapterFoo()).build()
如果要在CommonResponse中包装多个类型,则可能必须创建多个自定义适配器来容纳所有不同的类型