我是Android开发的新手,我正在尝试从服务器获取数据。通用的JSON响应结构将是这样
{
"success": "1",
"data": [
{
"customers_id": 4,
"customers_gender": "0",
"customers_firstname": "TES IOS",
"customers_lastname": "TES IOS",
"customers_dob": "2018-12-27",
"email": "TES002@email.com",
"user_name": "TES002",
"customers_default_address_id": 0,
"customers_telephone
},
"message": "Successfully get user data from server"
}
“成功”和“消息”字段将相同(始终为字符串)。但是对于其他请求调用,“数据”可以不同。它可以发送用户数据,存储数据或产品数据,甚至产品阵列/产品列表。
所以我想制作通用的可重用类来捕获该JSON响应。该类将是这样,我将“数据”设置为Any,然后将其强制转换回User对象:
class ServerData(successStatus: Int, data: Any, message: String) {
val isSuccessfull : Boolean
val data : Any
val message : String
init {
isSuccessfull = successStatus != 0
this.data = data
this.message = message
}
}
界面是这样的:
interface LakuinAPI {
@FormUrlEncoded
@POST("processlogin")
fun performLogin(
@Field("kode_customer") outletCode: String,
@Field("password") password: String
): Call<ServerData>
}
然后在活动中使用它,如下面的代码:
private fun sendLoginDataToServer(outletCode: String, password: String) {
val call = lakuinAPI.performLogin(outletCode,password)
call.enqueue(object: Callback<ServerData> {
override fun onFailure(call: Call<ServerData>, t: Throwable) {
Toast.makeText(this@LoginActivity,t.localizedMessage,Toast.LENGTH_LONG).show()
}
override fun onResponse(call: Call<ServerData>, response: Response<ServerData>) {
if (!response.isSuccessful) {
Toast.makeText(this@LoginActivity,"Code: " + response.code(),Toast.LENGTH_LONG).show()
return
}
val lakuinServerData = response.body()
val userList = lakuinServerData?.data as List<User> // the error in here
val userData = userList.first() // the error in here
println(userData)
}
})
}
但我收到错误消息:
java.lang.ClassCastException:com.google.gson.internal.LinkedTreeMap 无法转换为com.ssss.lakuinkotlin.Model.User
我在错误位置上方的代码中给出注释。我不知道为什么会这样。
老实说,如果这是从一般响应JSON(如上面的JSON)中捕获用户数据的正确方法,我不是。有更好的方法吗?
答案 0 :(得分:1)
您可以使用泛型来实现
class Response<Data> constructor() : ResponseSimple() {
@SerializedName(FIELD_DATA)
var data: Data? = null
private constructor(data: Data) : this() {
this.data = data
}
companion object {
const val FIELD_SUCCESS = "success"
const val FIELD_ERROR = "error"
const val FIELD_DATA = "data"
const val FIELD_MESSAGE = "message"
@JvmStatic
fun <Data> create(data: Data): Response<Data> {
return Response(data)
}
}
}
ResponseSimple
是
open class ResponseSimple {
@SerializedName(Response.FIELD_ERROR)
var error: String = ""
@SerializedName(Response.FIELD_SUCCESS)
var succes: Boolean = false
@SerializedName(Response.FIELD_MESSAGE)
var message:String = ""
}
然后api响应应该为Call<Response<ServerData>>
。
关于ClassCastException
,您不能仅使用ServerData
将User
转换为as
。
您需要使用Call<Response<ArrayList<User>>>
或创建类转换器。
答案 1 :(得分:0)
尝试替换此行:
val userList = lakuinServerData?.data as List<User>
具有:
val userList = lakuinServerData?.data as new TypeToken<List<User>>(){}.getType()