Retrofit + Gson + RxJava解析失败时抛出错误

问题描述 投票:0回答:1

使用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时,是否可能使改造抛出错误?

android kotlin gson retrofit rx-java
1个回答
1
投票
首先,这有点奇怪,当发生登录错误时,来自服务器的恢复不会触发可观察对象的错误。可能有一些后端问题?

[不幸的是,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( ... )

© www.soinside.com 2019 - 2024. All rights reserved.