1

Stackoverflowで尋ねられたこの質問と同様に、JAXBを使用してリストをルート要素として表すと、同じ問題が発生します。答えに概説されている解決策は私にはうまくいきませんが。

注:マッピングを行うためにJacksonfasterxmlライブラリを使用しています。

基本的に、私はAPI(繰り返しAPI)からいくつかのXMLを消費しています。APIによって返されるメッセージの1つには、ルート要素がリストとして含まれています。デモを以下に示します。

<plans type="array">
    <plan href="...">
    ...
    </plan>
    <plan href="...">
    ...
    </plan>
</plans>

上記をキャプチャするために、次のJavaクラス+JAXBアノテーションを作成しました。

@XmlRootElement(name = "plans")
public class Plans extends RecurlyObject {

    @XmlElement(name = "plan", type = Plan.class)
    private List<Plan> plans;

    public List<Plan> getPlans() { return this.plans; }

    public void setPlans(final List<Plan> plans) { this.plans = plans; }
    ...
}

これは機能しません。私が読んだドキュメントと記事は、リストの要素にカスタムタイプではなく文字列を使用して、上記のすべてのデモを読みました。

上記を実行すると、次のエラーが発生します。

原因:com.fasterxml.jackson.databind.JsonMappingException:
タイプ[simple type、classcom.ning.billing.recurly.model.Plan]の値をJSON文字列からインスタンス化できません。単一文字列のコンストラクタ/ファクトリメソッドはありません(参照チェーンを介して:com.ning.billing.recurly.model.Plans ["plan"])

私も次のことを試しましたが、同様の問題が発生します:

@XmlRootElement(name = "plans")
public class Plans extends RecurlyObject {
    @XmlTransient
    public static final String PLANS_RESOURCE = "/plans";

    @XmlElementWrapper(name = "plans")
    @XmlElement(name = "plan", type = Plan.class)
    private List<Plan> plans;

    public List<Plan> getPlans() { return this.plans; }

    public void setPlans(final List<Plan> plans) { this.plans = plans; }
    ...
}

エラーが発生しないようにする唯一の方法は、文字列を受け取るPlanクラスにctorを作成する場合です。しかし、myList<Plan>はPlanオブジェクトのリストであり、すべてのPlanのサブノードごとに1つです:(

ところで-PlanJavaクラスは正常に機能します-私はそれを使用して、他のAPI呼び出しから個々のPlanメッセージを受信します。

では、JAXBを使用して文字列以外のもののリストであるルート要素をJavaオブジェクトに正しくマップする方法はありますか?

乾杯

アップデート

次のソリューションは、stackoverflowの外部でPierreによって提供されました。

これをJacksonで動作させることは可能です。次のコードを参照してください。

@XmlRootElement(name = "plans")
public class Plans extends RecurlyObjects<Plan> {
}

注意すべき重要な詳細はですextends RecurlyObjects<Plan>RecurlyObjects本質的にArrayListです。

@JsonIgnoreProperties(ignoreUnknown = true)
public abstract class RecurlyObjects<T extends RecurlyObject> extends ArrayList<T> {
}

これで正常に動作するようになりました。

4

1 に答える 1

2

デフォルトでは、プロパティに注釈を付ける必要があります。可能な場合はマッピングを簡略化しました。

package forum11748159;

import java.util.List;
import javax.xml.bind.annotation.*;

@XmlRootElement
public class Plans extends RecurlyObject {

    private List<Plan> plans;

    @XmlElement(name = "plan")
    public List<Plan> getPlans() { return this.plans; }

    public void setPlans(final List<Plan> plans) { this.plans = plans; }

}

@XmlAccessorType(XmlAccessType.FIELD)フィールドに注釈を付ける場合は、クラスに注釈を追加する必要があります。

package forum11748159;

import java.util.List;
import javax.xml.bind.annotation.*;

@XmlRootElement(name = "plans")
@XmlAccessorType(XmlAccessType.FIELD)
public class Plans extends RecurlyObject {

    @XmlElement(name = "plan")
    private List<Plan> plans;

    public List<Plan> getPlans() { return this.plans; }

    public void setPlans(final List<Plan> plans) { this.plans = plans; }

}

注:マッピングを行うためにJacksonfasterxmlライブラリを使用しています。

JacksonはJAXBアノテーションのサポートを提供していますが、私が知る限り、JAXB(JSR-222)準拠の実装ではありません。仕様に従ってJAXBアノテーションを解釈することは保証されていません。

于 2012-07-31T21:01:38.500 に答える