Retrofit2 + SimpleXML in Kotlin: MethodException: Annotation must mark a set or get 方法
Retrofit2 + SimpleXML in Kotlin: MethodException: Annotation must mark a set or get method
我想从 API 获取 XML 数据,并在 Kotlin 中使用 Retrofit2 + SimpleXML 将其映射到 Kotlin 模型对象。
但是,我从 SimpleXML.
收到了如下错误信息
org.simpleframework.xml.core.MethodException: Annotation @org.simpleframework.xml.Element(data=false, name=, required=true, type=void) must mark a set or get method
这是获取的XML数据
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
<result code="0">Success</result>
<token>XXXXXXXXXXXXXXXXXXXX</token>
<uid>4294967295</uid>
</response>
Kotlin 模型对象如下
@Root(name = "response")
public class User() {
@Element public var result: String? = null
@Element public var token: String? = null
@Element public var uid: String? = null
}
和API客户端如下
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)
}
我得到了 HTTP 状态代码 200 并更正了 XML 数据。所以我认为我的模型对象声明有问题。
不熟悉 SimpleXml 库,但如果它的注释处理器正在寻找特定的获取和设置方法,您可能想尝试按以下方式设置您的 class:
@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
}
另外,如果@Element 注释支持字段类型,您可以使用此方法:
@Root(name="response") class User() {
@Element @JvmField var result:String?=null
@Element @JvmField var token:String?=null
@Element @JvmField var uid:String?=null
}
这是同一个问题:
您需要使用 Annotation use-site targets,因为 属性 上注释的默认优先级为:
- 参数(如果在构造函数中声明)
- 属性(如果目标站点允许,但只有 Kotlin 创建的注释可以做到这一点)
- 字段(可能这里发生了什么,这不是你想要的)。
使用 get
或 set
目标将注释放置在 getter 或 setter 上。这是 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
}
详情见。
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
}
我想从 API 获取 XML 数据,并在 Kotlin 中使用 Retrofit2 + SimpleXML 将其映射到 Kotlin 模型对象。
但是,我从 SimpleXML.
收到了如下错误信息org.simpleframework.xml.core.MethodException: Annotation @org.simpleframework.xml.Element(data=false, name=, required=true, type=void) must mark a set or get method
这是获取的XML数据
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
<result code="0">Success</result>
<token>XXXXXXXXXXXXXXXXXXXX</token>
<uid>4294967295</uid>
</response>
Kotlin 模型对象如下
@Root(name = "response")
public class User() {
@Element public var result: String? = null
@Element public var token: String? = null
@Element public var uid: String? = null
}
和API客户端如下
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)
}
我得到了 HTTP 状态代码 200 并更正了 XML 数据。所以我认为我的模型对象声明有问题。
不熟悉 SimpleXml 库,但如果它的注释处理器正在寻找特定的获取和设置方法,您可能想尝试按以下方式设置您的 class:
@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
}
另外,如果@Element 注释支持字段类型,您可以使用此方法:
@Root(name="response") class User() {
@Element @JvmField var result:String?=null
@Element @JvmField var token:String?=null
@Element @JvmField var uid:String?=null
}
这是同一个问题:
您需要使用 Annotation use-site targets,因为 属性 上注释的默认优先级为:
- 参数(如果在构造函数中声明)
- 属性(如果目标站点允许,但只有 Kotlin 创建的注释可以做到这一点)
- 字段(可能这里发生了什么,这不是你想要的)。
使用 get
或 set
目标将注释放置在 getter 或 setter 上。这是 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
}
详情见
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
}