android - rxjava - Retrofit2+SimpleXML en Kotlin: MethodException: la anotación debe marcar un conjunto u obtener un método
retrofit singleton kotlin (3)
Quiero obtener datos XML de la API y asignarlos al objeto modelo de Kotlin utilizando Retrofit2 + SimpleXML en Kotlin.
Sin embargo, recibí el siguiente mensaje de error de SimpleXML.
org.simpleframework.xml.core.MethodException: Annotation @ org.simpleframework.xml.Element (data = false, name =, required = true, type = void) debe marcar un conjunto o método de obtención
Esto es recuperado de datos XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
<result code="0">Success</result>
<token>XXXXXXXXXXXXXXXXXXXX</token>
<uid>4294967295</uid>
</response>
El objeto modelo de Kotlin está abajo.
@Root(name = "response")
public class User() {
@Element public var result: String? = null
@Element public var token: String? = null
@Element public var uid: String? = null
}
y APIClient es como sigue.
interface MyService {
@GET("/testLogin.xml")
fun getUser(): Call<User>
}
val retrofit = Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(SimpleXmlConverterFactory.create())
.build()
val call = retrofit.create(MyService::class.java).getUser()
call.enqueue(object: Callback<User> {
override fun onResponse(p0: Call<User>?, response: Response<User>?) {
val response = response?.body()
}
override fun onFailure(p0: Call<User>?, t: Throwable?) {
Log.e("APIClient", t?.message)
}
Tengo el código de estado HTTP 200 y datos XML correctos. Así que creo que mi declaración de objeto modelo es un problema.
No está familiarizado con la biblioteca SimpleXml, pero si su procesador de anotaciones está buscando métodos específicos de configuración y obtención, puede intentar configurar su clase de la siguiente manera:
@Root(name="response") class User() {
var result:String?=null
@Element
get
@Element
set
var token:String?=null
@Element
get
@Element
set
var uid:String?=null
@Element
get
@Element
set
}
Además, si la anotación @Element admite tipos de campo, podría utilizar este enfoque:
@Root(name="response") class User() {
@Element @JvmField var result:String?=null
@Element @JvmField var token:String?=null
@Element @JvmField var uid:String?=null
}
Este es el mismo problema que: kotlin data class + bean validation jsr 303
Debe usar los objetivos del sitio de uso de Anotación, ya que el valor predeterminado para una anotación en una propiedad se prioriza como:
- parámetro ( si se declara en constructor )
- propiedad ( si el sitio de destino lo permite, pero solo las anotaciones creadas por Kotlin pueden hacer esto )
- campo ( probablemente lo que pasó aquí, que no es lo que querías ).
Use get
o set
target para colocar la anotación en el getter o setter. Aquí está para el getter:
@Root(name = "response")
public class User() {
@get:Element public var result: String? = null
@get:Element public var token: String? = null
@get:Element public var uid: String? = null
}
Vea la respuesta vinculada para los detalles.
To avoid the error in parse do one should place annotation tags @set e @get
@Root(name = "response", strict = false)
public class User() {
@set:Element(name = "result")
@get:Element(name = "result")
public var result: String? = null
@set:Element(name = "token")
@get:Element(name = "token")
@Element public var token: String? = null
@set:Element(name = "uid")
@get:Element(name = "uid")
public var uid: String? = null
}