Android 如何使用改型、rxjava和dagger为错误创建通用响应处理程序并验证响应

Android 如何使用改型、rxjava和dagger为错误创建通用响应处理程序并验证响应,android,kotlin,retrofit2,dagger-2,rx-java2,Android,Kotlin,Retrofit2,Dagger 2,Rx Java2,我正在尝试创建通用体系结构来使用复杂的json结构,如下所示: Json格式 } 匕首格式 @Singleton fun provideGson():Gson= GsonBuilder() .setLenient() //.registerTypeAdapter(BaseResponse::class.java,RestDeserializer()) .create() Rest反序列化程序 类重新反序列化器:JsonDeserializer{ @抛出(JsonParseException::

我正在尝试创建通用体系结构来使用复杂的json结构,如下所示:

Json格式

}

匕首格式

@Singleton
fun provideGson():Gson=
GsonBuilder()
.setLenient()
//.registerTypeAdapter(BaseResponse::class.java,RestDeserializer())
.create()
Rest反序列化程序

类重新反序列化器:JsonDeserializer{
@抛出(JsonParseException::类)
重写有趣的反序列化(je:JsonElement,类型:type,jdc:JsonDeserializationContext):T{
val content=je.asJsonObject
//反序列化它。您使用一个新的Gson实例来避免无限递归
//到这个反序列化程序
返回Gson().fromJson(内容,类型)
}
}

错误回调

抽象类ErrorCallBack:DisposableObserver(){
成功时受保护的抽象乐趣(t:t)
覆盖下一个(t:t){
//您可以从API返回不同情况的状态码,并在这里进行处理。我通常在BaseResponse中包含这些情况,并从每个响应中删除它们
成功(t)
}
覆盖有趣的错误(e:可丢弃){
何时(e){
是HttpException->{
val responseBody=(e).response().errorBody()
回应书?,让我来{
L.e(“调用htttp异常中的错误”)
}
}
SocketTimeoutException->{
//待办事项
L.e(“插座超时错误”)
}
是IOException->{
//待办事项
L.e(“IO异常中的错误”)
}
其他->{
e、 留言?让我说{
//待办事项
}
}
}
}
覆盖有趣的onComplete(){
}
private fun getErrorMessage(responseBody:responseBody):字符串{
回击{
val jsonObject=jsonObject(responseBy.string())
jsonObject.getString(“消息”)
}捕获(e:例外){
e、 留言!!
}
}
}

存储库

覆盖getValidateUser(validateUser:validateUser):LiveData{
val mutableLiveData=mutableLiveData()
remoteServices.requestValidateUser(validateUser)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribowith(对象:ErrorCallBack(){
成功时覆盖乐趣(t:BaseResponse){
if(t.type==CommonContents.SUCCESS){
L.d(“验证用户成功”)
mutableLiveData.value=转换(t)
}否则{
L.e(“验证用户错误”)
}
}
})
返回可变LiveData
}
数据

数据类基本响应(
@SerializedName(CommonContents.TYPE)val类型:字符串,
@SerializedName(CommonContents.CODE)val代码:字符串,
@SerializedName(CommonContents.DESCRIPTION)val描述:字符串,
@SerializedName(CommonContents.RESULT)val结果:T?=null)
这些是我的结构,我试图创建一个通用结构,但在调用错误回调时遇到了一个问题

请指导我如何实现这一点。我可以在泛型响应中调用泛型方法吗?

  .subscribeWith(object : ErrorCallBack<BaseResponse<ValidateUserResponse>>() {
.subscribowith(对象:ErrorCallBack(){

实现工作代码指南

这是我的一些代码工作指南。它基于的原则

  • 在IDE中设置单元测试环境。就我个人而言,我一直在使用JUnit4和Eclipse,但您可能更喜欢JUnit5和JetBrains的IDE
  • ErrorCallback
    类构造函数编写一个单元测试。让它通过。接下来,为每个方法编写单元测试,以查看它的行为是否符合预期
  • 编写单元测试,其中您的测试夹具是一个
    PublishSubject
    ,用于一些不同的情况:正常数据、正常数据序列、正常数据后跟错误、正常数据后跟完成
  • 在此基础上,添加更多测试,以便可以测试整个可观察链
  • @Singleton
    fun provideGson(): Gson =
            GsonBuilder()
                    .setLenient()
                 //   .registerTypeAdapter(BaseResponse::class.java, RestDeserializer<BaseResponse<T>>())
                    .create()
    
     class RestDeserializer<T> : JsonDeserializer<T> {
    @Throws(JsonParseException::class)
    override fun deserialize(je: JsonElement, type: Type, jdc: JsonDeserializationContext): T? {
        val content = je.asJsonObject
    
        // Deserialize it. You use a new instance of Gson to avoid infinite recursion
        // to this deserializer
        return Gson().fromJson<T>(content, type)
    
    }
    
    abstract class ErrorCallBack<T : BaseResponse<T>> : DisposableObserver<T>() {
    
    protected abstract fun onSuccess(t: T)
    
    override fun onNext(t: T) {
        //You can return StatusCodes of different cases from your API and handle it here. I usually include these cases on BaseResponse and iherit it from every Response
        onSuccess(t)
    }
    
    override fun onError(e: Throwable) {
    
        when (e) {
            is HttpException -> {
                val responseBody = (e).response().errorBody()
                responseBody?.let {
                    L.e("Error in call htttp exception")
                }
            }
            is SocketTimeoutException -> {
                // todo
                L.e("Error in Socket time out")
            }
            is IOException -> {
                // todo
                L.e("Error in IO Exception")
            }
            else -> {
                e.message?.let {
                    // todo
                }
            }
        }
    }
    
    override fun onComplete() {
    
    }
    
    private fun getErrorMessage(responseBody: ResponseBody): String {
        return try {
            val jsonObject = JSONObject(responseBody.string())
            jsonObject.getString("message")
        } catch (e: Exception) {
            e.message!!
        }
    
    }
    
        override fun getValidateUser(validateUser: ValidateUser): LiveData<ValidateUserResponse> {
    
        val mutableLiveData = MutableLiveData<ValidateUserResponse>()
        remoteServices.requestValidateUser(validateUser)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(object : ErrorCallBack<BaseResponse<ValidateUserResponse>>() {
                    override fun onSuccess(t: BaseResponse<ValidateUserResponse>) {
                        if (t.type == CommonContents.SUCCESS) {
                            L.d("Success in validate user")
                            mutableLiveData.value = transform(t)
                        } else {
                            L.e("Validate User Error")
                        }
                    }
                })
        return mutableLiveData
    }
    
    data class BaseResponse<out T>(
        @SerializedName(CommonContents.TYPE) val type: String,
        @SerializedName(CommonContents.CODE) val Code: String,
        @SerializedName(CommonContents.DESCRIPTION) val Description: String,
        @SerializedName(CommonContents.RESULT)val result: T? = null)
    
      .subscribeWith(object : ErrorCallBack<BaseResponse<ValidateUserResponse>>() {