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> {
}
これで正常に動作するようになりました。