studio rxjava example enqueue android kotlin simple-framework retrofit2

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 }