【问题标题】:Retrofit+Gson+RxJava throw error on parsing failedRetrofit+Gson+RxJava 解析失败时抛出错误
【发布时间】:2020-08-03 05:32:20
【问题描述】:

我在使用 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 对象调用订阅成功。并且该对象在不能为空的字段上具有空值。

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 解析失败而不是发出空对象时,是否可以进行改造抛出错误?

【问题讨论】:

    标签: android kotlin gson retrofit rx-java


    【解决方案1】:

    首先,这有点奇怪,当登录错误发生时,来自服务器的响应不会触发 observable 的错误。可能有一些后端问题?

    其次,不幸的是,Gson 不是 null 安全的,因为它使用反射来解析对象,所以如果没有提供,即使不是可以为 null 的字段也可以具有 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( ... )
    

    【讨论】:

    • 莫鲁,谢谢你的回答。在阅读了 Gson 中的空安全问题 3 小时后,我决定使用我自己的调用适配器,在那里我得到原始响应字符串并手动解析它或抛出错误。
    猜你喜欢
    • 2020-03-15
    • 2020-08-22
    • 2016-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-19
    相关资源
    最近更新 更多