JAXB - 将根元素表示为自定义类型列表

时间:2012-07-31 20:09:45

标签: jaxb

与Stackoverflow using JAXB to represent a list as the root element上提出的问题类似,我遇到了同样的问题。虽然答案中概述的解决方案对我不起作用。

注意:我正在使用Jackson的quickxml lib进行映射。

Essentialy我正在从API(reurly api)中使用一些XML。 API返回的消息之一将根元素作为列表,演示如下所示:

<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; }
    ...
}

这不起作用。文档&amp;文章我已经阅读了上面使用字符串演示的所有内容而不是列表元素的自定义类型。

运行上述内容会产生以下错误:

引起:com.fasterxml.jackson.databind.JsonMappingException:无法实例化值
   来自JSON String的[simple type,class com.ning.billing.recurly.model.Plan]类型;没有    单字符串构造函数/工厂方法(通过引用链:    com.ning.billing.recurly.model.Plans [ “计划”])

我也尝试了以下内容 - 但产生了类似的问题:

@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。但是我的List<Plan>是一个Plan对象列表,一个用于所有计划的每个子节点:(

BTW - 计划Java类工作正常 - 我用它来接收来自其他API调用的单独计划消息。

那么,任何想法如何使用JAXB正确地将除了Strings之外的其他东西列表的根元素映射到Java对象中?

干杯

更新

以下解决方案由stackoverflow之外的Pierre提供。

有可能让这与杰克逊合作看到以下代码:

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

现在工作正常。

1 个答案:

答案 0 :(得分: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; }

}

  

注意:我使用Jackson的fastxml lib来进行映射。

Jackson为JAXB注释提供了一些支持,但据我所知,这不是JAXB (JSR-222)兼容的实现。不保证根据规范解释JAXB注释。