web-dev-qa-db-ja.com

KotlinのRetrofit2 + SimpleXML:MethodException:アノテーションはセットまたは取得メソッドをマークする必要がある

APIからXMLデータをフェッチし、KotlinでRetrofit2 + SimpleXMLを使用してKotlinモデルオブジェクトにマッピングしたいと考えています。

しかし、SimpleXMLから以下のようなエラーメッセージが出ました。

org.simpleframework.xml.core.MethodException:アノテーション@ org.simpleframework.xml.Element(data = false、name =、required = true、type = void)は、セットまたは取得メソッドをマークする必要があります

これはフェッチされた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
}

aPIClientは次のとおりです。

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データを修正しました。だから私はモデルオブジェクトの宣言が問題だと思います。

22
c8112002

これは次と同じ問題です: kotlin data class + bean validation jsr 3

プロパティのアノテーションのデフォルトは次のように優先されるため、 Annotation use-site targets を使用する必要があります。

  • parameterコンストラクタで宣言されている場合
  • propertyターゲットサイトで許可されているが、Kotlinで作成されたアノテーションのみがこれを実行できる場合
  • fieldおそらくここで何が起こったか、それはあなたが望んでいたことではありません)。

getまたはsetターゲットを使用して、アノテーションをゲッターまたはセッターに配置します。これはゲッター用です:

@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
}

詳細は リンクされた回答 を参照してください。

28
Jayson Minard
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
}
4
Tairo Roberto

SimpleXmlライブラリに精通していませんが、それがアノテーションプロセッサで特定のgetメソッドとsetメソッドを探している場合は、次の方法でクラスを設定してみてください。

@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
}
2
Matt Sams