如何在Kotlin中使用Retrofit2解析接口返回的JSON响应
解决方案
你当前使用的是Gson序列化库配合Retrofit做网络请求,对应Swift的Codable能力,Gson的@SerializedName注解已经帮你完成了字段映射,以下是两种实现解析的方式,以及现有代码的问题修正:
方案1:直接让Retrofit自动解析(推荐)
不需要自己手动处理ResponseBody,直接修改接口定义的返回类型即可:
//Interface 修改后 interface PostInterface { class User( val email: String, val password: String ) @POST("signIn") // 把返回类型从Call<ResponseBody>改成Call<SignInModel> fun signIn(@Body user: User): Call<SignInModel> }
对应网络请求的onResponse部分直接取解析好的实例:
override fun onResponse(call: Call<SignInModel>, response: Response<SignInModel>) { if (response.code() == 200) { try { val signInModel = response.body() status.value = Resource.success(signInModel) } catch (ex: Exception) { parseError(400, response.errorBody()?.string()?:"", status) } } else { //do something... } }
方案2:手动解析ResponseBody(如果必须保留原有接口定义)
如果不能修改接口返回类型,直接用Gson把ResponseBody的内容转成SignInModel即可:
override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) { if (response.code() == 200) { try { response.body()?.let { body -> val gson = Gson() val signInModel = gson.fromJson(body.charStream(), SignInModel::class.java) status.value = Resource.success(signInModel) }?: run { // 响应体为空的异常处理 parseError(400, "响应体为空", status) } } catch (ex: Exception) { parseError(400, ex.message?:"解析失败", status) } } else { //do something... } }
现有代码错误修正
你在按钮点击的观察逻辑里调用的字段和方法名和你定义的不一致,需要修改:
//SignIn Button 修改后 viewModel.signIn().observe(viewLifecycleOwner, androidx.lifecycle.Observer { v -> if (v.status == Resource.Status.SUCCESS) { val model = v.data as SignInModel // 字段名要和SignInModel里定义的一致,不要直接强转避免空指针 pref.setBearerToken(model.bearerToken ?: "") pref.setStaySignIn(model.staySignIn ?: false) } else if (v.status == Resource.Status.ERROR) { //do something... } })
如果项目里已经配置了全局的Gson实例,直接复用即可,不需要每次创建新的Gson对象。
内容的提问来源于stack exchange,提问作者14079_Z
相关产品推荐
相关产品推荐

