【问题标题】:Retrofit API call: How to make sure that value is not null after making api call?改造 API 调用:如何在进行 api 调用后确保该值不为空?
【发布时间】:2018-02-01 05:14:31
【问题描述】:

我有以下 AuthenticationResponse 模型,我使用 retrofit2 进行 3 个 api 调用。如果我拨打 verifyEmail 电话 f.e. JSON 响应正文仅包含有效电子邮件的属性(例如 {"validEmail": true} )。其他 2 个调用仅包含“resetSuccesful”或其他 4 个的属性。

当我收到对 verifyEmail 调用 f.e. 的响应时,如何确保/检查这一点是否包含validEmail 的非空值??

服务:

interface AuthenticationService {

@POST("auth/checkEmail")
fun verifyEmail(@Body email: String): Call<AuthenticationResponse>

@POST("auth/login")
fun login(@Body loginCredentials: LoginCredentials): Call<AuthenticationResponse>

@POST("auth/resetPassword")
fun resetPassword(@Body email: String): Call<AuthenticationResponse>
}

型号:

data class AuthenticationResponse(

    val validEmail: Boolean? = null,

    val loginSuccess: Boolean? = null,
    val retriesLeft: Int? = null,
    val authToken: String? = null,
    val accountBlocked: Boolean? = null,

    val resetSuccesful: Boolean? = null)

编辑: 如果我模拟我的服务器响应以返回 f.e. responseCode = 200 - { "validEmail": null } 并将 validEmail 类型更改为 Boolean(而不是 Boolean?)Retrofit 不会引发任何类型的异常(这是我真正想要的)因此我的模型给了我一个错误的否定我的有效电子邮件值..

【问题讨论】:

  • 你为什么有单AuthenticationResponse?似乎对每个 API 调用使用单独的响应模型会更明智。
  • @miensol:是的,拥有单独的响应模型肯定会解决问题。但我把问题放在这里是因为我真的很想知道是否还有其他方法/一种方法可以确保某个值不为空

标签: kotlin retrofit retrofit2 notnull


【解决方案1】:

您绝对应该考虑@miensol 的评论——为不同的 API 调用提供单独的模型对象。

但是,如果这不可行,您可以使用Sealed class

sealed class AuthenticationResponse {

    data class EmailValidation(val validEmail: Boolean) : AuthenticationResponse()
    data class SomeSecondResponse(val loginSuccess: Boolean, ...) : AuthenticationResponse()
    data class SomeThirdResponse(val resetSuccessful: Boolean) : AuthenticationResponse()

}

fun handleResponse(response: AuthenticationResponse) {

    when (response) {
        is AuthenticationResponse.EmailValidation -> response.validEmail
        is AuthenticationResponse.SomeSecondResponse -> response.loginSuccess
        is AuthenticationResponse.SomeThirdResponse -> response.resetSuccessful
    }

}

Sealed class 是类固醇的枚举——它是带有状态的枚举。您必须为从密封类 AuthenticationResponse 继承的 3 个响应创建 3 个类。

您必须创建对应于不同 API 调用的特定类实例。要访问数据,您可以进行类型检查并访问特定数据。以上when 示例展示了如何访问函数内的所有响应类型。

当我收到对 verifyEmail 致电 f.e.它包含一个非空值 有效邮箱??

由于您只创建特定类的实例,并且所有类都只有非空属性,因此您不必担心空值。

【讨论】:

  • 我已经尝试过了,但似乎并没有像我想要的那样工作。如果我模拟我的服务器响应以返回 f.e. responseCode = 200 - { "validEmail": null } 并将 validEmail 类型更改为 Boolean(而不是 Boolean?)Retrofit 不会引发任何类型的异常,因此我的模型对我的 validEmail 值给出了误报..
  • 我没有在 Retrofit 工作过。所以我无法对此发表评论。高级想法是,例如,对于 validEmail API 调用,您必须创建一个 AuthenticationResponse.EmailValidation 的实例,该实例具有 validEmail 作为 Boolean 类型。所以如果你传递null,你会在那里得到一个异常。
【解决方案2】:

我会考虑@miensol 在评论中提到的内容,但如果您想为此添加检查,您可以执行以下操作:

fun isEmailValid(authResponse: AuthenticationResponse): Boolean {
    return authResponse.validEmail ?: false
}

请参阅 Elvis Operator 上的 Kotlin 文档:

如果?: 左边的表达式不为null,elvis 运算符返回它,否则返回右边的表达式。请注意,仅当左侧为空时才计算右侧表达式。

【讨论】:

  • 鲍勃的回答比我的要好,从长远来看,您应该如何处理您的响应。
猜你喜欢
  • 1970-01-01
  • 2012-07-31
  • 2019-01-17
  • 2018-01-18
  • 2019-08-12
  • 2018-01-20
  • 1970-01-01
  • 2017-01-11
  • 1970-01-01
相关资源
最近更新 更多