我有一个Web服务,它返回一个主题的用户列表,如果该主题没有任何用户,则只返回HTTP代码204(无内容)。
这是我对该服务的改造2(在Kotlin中)
@GET("/user/{topic}") fun getAllUserFor(@Path(value="topic",encoded=true) topic:String) :Observable<List<User>>
我的执行是:
fun getAllUsers(topic: String, onSuccess: Consumer<List<User>>, onFail:Consumer<Throwable>){
val api = NetworkLayer.getUserApi()
api.getAllUserFor(topic)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(onSuccess,onFail)
}
除非主题没有用户,否则工作正常,因为当没有用户服务器响应时,代码204作为例外接收。
我正在使用ScalarsConverterFactory&amp; GsonConverterFactory用Retrofit2解析Json响应。
类似问题讨论了here,但他们的服务器只响应没有任何内容的http代码!在我的情况下,当有一个或多个用户时,服务器将返回用户列表作为Json主体。没有用户时响应204,所以我需要处理这两种情况以及其他常见的http错误。
答案 0 :(得分:2)
您可以通过实现一个运算符来实现这一点,该运算符将检查接收到的响应的状态代码是否为204:
class OnApiErrorOperator : ObservableOperator<OnApiErrorOperator.User, Response<OnApiErrorOperator.User>> {
override fun apply(observer: Observer<in OnApiErrorOperator.User>): Observer<in Response<OnApiErrorOperator.User>> {
return object : Observer<Response<OnApiErrorOperator.User>> {
override fun onSubscribe(d: Disposable) {
observer.onSubscribe(d)
}
override fun onNext(response: Response<OnApiErrorOperator.User>) {
if (response.code() == 204) {
//return User object with empty list when response's status code is 204
observer.onNext(User(emptyList()))
} else {
if (response.isSuccessful) {
observer.onNext(response.body()!!)
} else {
//don't forget to check for other statuses
observer.onError(OnApiServerErrorException(response.code()))
}
}
}
override fun onError(e: Throwable) {
observer.onError(e)
}
override fun onComplete() {
observer.onComplete()
}
}
}
class User(
@SerializedName("user_info")
val userInfo: List<String>
)
class OnApiServerErrorException(val statusCode: Int) : Exception()
}
然后你可以在你的observables链中添加运算符lift
来调用它:
api.getAllUserFor(topic)
.subscribeOn(Schedulers.io())
.lift(OnApiErrorOperator())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(onSuccess, onFail)
答案 1 :(得分:2)
标准方法将响应包装在带有adapter-rxjava2依赖项的Result
中。
@GET("/user/{topic}")
fun getAllUserFor(@Path(value="topic",encoded=true) topic:String) :Observable<Result<List<User>>>
这样,错误也会传递到onNext,您可以执行以下操作:
api.getAllUserFor(topic)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe{ result ->
if(result.isError)
//Network Error
result.response()?.also {
if(result.isSuccessful)
//Success
else{
//api error
}
}
}
更干净,更简洁
使用
检查状态result.response?.code()
欢呼!