Android Retrofit2中解析errorBody(Kotlin语言)

1,298 阅读2分钟
我是个刚开始做Android的小白,写这篇博客就是为了记录工作中遇到的一些问(nao)题(tan)。

场景描述

在做登录业务的时候,需求要求客户端在登录失败时根据response返回的code来提示用户相关信息,比如账号密码不匹配,用户不存在······由于服务端的同事将错误信息进行了额外封装,然后放到了errorBody中向客户端返回。这时就需要拿出errorBody中的数据来进行信息提示。

解析步骤

第一步:拿到errorBody

// response是接口返回的响应
// 特别值得注意的是,这里一定要用string(),千万千万不要用toString()。具体原因后面会说
val errorBody = response.errorBody()?.string() 

第二步:解析json数据

导入Moshi开源库(当然也可以选择其他的开源库Gson之类的)
implementation 'com.squareup.moshi:moshi:1.8.0'
创建Moshi类
val moshi = Moshi.Builder().build()
解析errorBody
// 其中的ErrorBody::class.java是我之前创建好的实体类
// 由于errorBody是可能为空的,所以当errorBody为空时就传入一个空字符串
val formJson = moshi.adapter<ErrorBody>(ErrorBody::class.java).fromJson(errorBody ?: "")
ErrorBody::class,java实体类
// 因为我只用到了ErrorBody中的message和code,所以就只定义了这俩
// 也可以根据自己的需求来定制
data class ErrorBody(var message: String, var code: String)

第三步:获取数据

直接获取就可以了
// 解析后的fromJson就是一个对象,属性名是我们在实体类定义的属性名,属性值是json中的值
val message = fromJson?.message
val code = from?.code

为什么不用toString

当我知道自己的目标是errorBody的时候,我第一反应就是直接用 . 获取,但是 . 了半天没有errorBody中的content,然后知道了自己要解析。解析一开始就是直接用的toString()方法。不行,打印出来是一个十六进制的字符串,然后同事提示我用string()来做,toString()不行。果不其然,自己道行太浅了!

string()方法本身不是Kotlin或Java自带的方法,它是由OkHttp在ResponseBody中定义的,也就是说开源库的作者希望我们用它来获取实际字符串值,而不是toString()。toString()是转到Object那里,它以我们获得的形式返回对象。再准确一点,就是返回对象的十六进制表示。如果有疑问,可以直接打印出errorBody,就是一个16进制表示。

开源库中string()方法的原注释

  /**
   * Returns the response as a string decoded with the charset of the Content-Type header. If that
   * header is either absent or lacks a charset, this will attempt to decode the response body in
   * accordance to <a href="https://en.wikipedia.org/wiki/Byte_order_mark">its BOM</a> or UTF-8.
   */

翻译

以使用内容类型的字符集解码的字符串形式返回响应标题。如果该标头不存在或缺少字符集,这将尝试根据
<a href="https://en.wikipedia.org/wiki/Byte_order_mark">its BOM</a>对响应正文进行解码。