使用Retrofit + Gson + RxJava时出现一些奇怪的行为
这是我的取物对象
Retrofit.Builder()
.baseUrl(Constants.Urls.URL_BASE)
.addConverterFactory(GsonConverterFactory.create(Gson()))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(client)
.build()
这是我的数据类
data class User(
val id:Int,
val email:String,
val name:String)
这是我的改造界面
@Multipart
@POST(Constants.Urls.URL_LOGIN)
fun makeLogin(@PartMap map: Map<String, String?>): Observable<Model_User>
登录成功后,所有操作均应正常进行,但是当响应而不是json对象时,我得到奇怪的行为,例如出现字符串错误。
{
"error": {
"code": 400,
"message": "Wrong password"
}
}
Observable调用带有User对象的订阅成功。并且此对象在不能为null的字段上具有null值。
my_api.makeLogin(map)
.subscribe(
{
//Here i got User(id = null,email = null,name = null)
},
{
//But i need to call error here on parsing failed
})
在调用onNext之前我应该怎么做以引发错误?当Gson解析失败而不是发出空Object时,是否可能使改造抛出错误?
[不幸的是,Gson不是空值安全的,因为它使用反射来解析对象,因此,如果没有提供空值,则即使不为空的字段也可以具有null
值(例如,参见this article)。他们甚至提供了feature request来提供强制执行异常的机制,然后请求的字段不在json中(保留了5年)。
目前,处理此问题的最佳选择可能是创建两个不同的模型:所有字段都可以为空的API模型,域模型(您已经拥有的User
模型)和flatMap映射结果。例如:
my_api.makeLogin(map)
.flatMap { apiUser ->
try {
val user = apiUser.mapToDomain() //throw exception while mapping if field is missing
Single.just(user)
}catch(e: Exception){
Single.error<User>(IllegalStateException())
}
}
.subscribe( ... )