JAXB 和 MOXy 在 Jersey 中对泛型列表进行 XML 和 JSON 编排

3
我正在使用Jersey创建一个小型的RESTful客户端,并且在支持XML和JSON编组时遇到了一些问题。
具体问题是如何对包含几个属性和通用列表的对象进行编组。
我有以下按照注释的类:
@XmlRootElement
public class Block<E> {

    private String headerText;

    private List<E> elements;

    public Block() {
    }

    @XmlElement
    public String getHeaderText() {
        return headerText;
    }

    @XmlElementWrapper(name = "elements")
    @XmlElements({
        @XmlElement(name = "element", type=Foo.class),
        @XmlElement(name = "element", type=Bar.class)
    })
    public List<E> getElements() {
        return elements;
    }
}

XML格式正确:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<block>
<elements>
    <element>
        <id>1</id>
        <title>Title01</title>
    </element>
    <element>
        <id>2</id>>
        <title>Title02</title>
    </element>
</elements>
<headerText>FooBarHeader</headerText>
</block>

但是JSON的格式是像这样的:
{
-elements : {
    -element: [
         - {
            id : 1
            title : "Title01"
        }
         - {
            id : 2
            title : "Title02"
        }
    ]
}
headerText : "HeaderText"
}

我当然希望在我的JSON输出中不要有"element"属性,只有elements: [{}...{}]

我已经设置了一个ContextResolver,它创建了一个具有JSON_WRAPPER_AS_ARRAY_NAME属性的MOXyConfig - 对于例如List<String>这样的情况,我只需要用@XmlElement声明属性,而不是@XmlElements

有谁知道解决这个问题的方法吗?


通常,在@XmlElements注释中的@XmlElement注释具有不同的名称。我注意到您给它们相同的名称,这是有意为之吗?FooBar是否属于同一继承层次结构? - bdoughan
在这个基本的模板代码中,我只是使用了复制/粘贴,因此在@XmlElement注释中使用了相同的名称。 Foo和Bar可能是两个完全不同的类,彼此之间可能没有关系。 - Martin Hansen
我也遇到了完全相同的问题。对我来说,它看起来像一个moxy bug。你已经追踪过它或者通过任何解决方法解决了这个问题吗? - Robert Kornmesser
我们选择放弃使用xml,而是直接使用jackson作为提供者。实际上,Jackson非常好用,我认为它更容易使用。 - Martin Hansen
@XmlElementRef 也可能出现类似的问题。在发现您的问题之前,我已经提交了一个错误报告。不幸的是,MOXy 看起来已经处于停滞状态了。 :-( - Hein Blöd
2个回答

1

JSON_WRAPPER_AS_ARRAY_NAME 属性

JSON_WRAPPER_AS_ARRAY_NAME 属性的作用取决于项名称是否重要(请参阅:http://blog.bdoughan.com/2013/03/binding-to-json-xml-handling-collections.html)。

不重要的项名称

以下我们知道集合中的每个项都是 Foo 的实例或 Foo 的子类的实例。

@XmlElementWrapper(name = "elements")
@XmlElement(name = "element")
public List<E> getElements() {
    return elements;
}

重要的项目名称

在使用@XmlElements时,项目名称非常重要,因为它告诉我们需要在解组时实例化哪个类,并且不能被排除。

@XmlElementWrapper(name = "elements")
@XmlElements({
    @XmlElement(name = "foo", type=Foo.class),
    @XmlElement(name = "bar", type=Bar.class)
})
public List<E> getElements() {
    return elements;
}

你可以做什么

你可以使用MOXy的外部映射文档来覆盖元素属性的映射,具体操作如下:

@XmlElementWrapper(name = "elements")
@XmlElement(name = "foo")
public List<E> getElements() {
    return elements;
}

然后XML的JAXBContext将基于注解,而JSON的JAXBContext将基于注解和外部映射文档。 更多信息请参见。

没有解决我的问题。JSON输出格式仍然与主题中显示的相同,只是属性名称为“foo”或“bar”,而不是“element”。无论如何,干杯 - Martin Hansen

1
尝试注册另一个JSON实体提供程序,这将自动禁用Moxy进行JSON编组(参见ref)。如果您启用例如Jackson,则将具有其自己的注释来控制如何编组所有内容。

我已经注册了Jackson,它运行得很好。但是我希望只需要应用一种类型的注释,而不是两种,因为我必须支持XML和JSON。虽然标记为有用的答案。谢谢 :) - Martin Hansen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接