JAXB 映射到 JSON

14
我编写了一个JAX-RS(Jersey)REST服务,它接受ONIX XML格式的XML消息。通常,我使用xjc从给定的架构生成了所有所需的JAXB绑定类。总共有500多个类,我无法修改它们。
现在,当我有一个JAXB映射对象时,我需要将其存储到数据库中。我使用mongoDb,因此消息格式应该是JSON。我尝试使用带有JAXB模块的Jackson将JAXB对象转换为JSON,这在存储数据方面非常有效。但是,当我尝试将JSON转换回JAXB对象时,它会抛出与JAXBElement相关的异常。在Google上,我发现Jackson不支持JAXBElement,我必须解决这个问题。但是我无法这样做,因为我无法修改JAXB生成的类。
是否有一种方式可以使用其他手段将JAXB对象映射到JSON,但是仍遵循整个JAXB规范,以便今后从JSON转换为JAXB对象没有任何问题?

1
杰克逊应该根据 使用JAXB注释与杰克逊 支持该注释。 - Prmths
1
你也可以直接使用JAXB。这里有一篇很好的文章:绑定到JSON和XML - 处理集合 - Prmths
2
@Prmths - 我已经添加了一个回答,扩展了你的评论:https://dev59.com/9GIk5IYBdhLWcg3wke3M#19168878 - bdoughan
@BlaiseDoughan,感谢您提供的参考。在处理MOXy或JAXB时,我几乎会寻找您编写的任何内容。 - Prmths
如果你在这个旧问题中发现了自己,请查看这个问题 - Sebastian Barth
2个回答

18

注意: 我是EclipseLink JAXB (MOXy)的负责人,也是JAXB (JSR-222)专家组的成员。

如果你无法使用Jackson,那么你可以使用MOXy。

Java模型

Foo

这是一个包含JAXBElement类型字段的示例类。

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {

    @XmlElementRef(name="bar")
    private JAXBElement<Bar> bar;

}

酒吧

public class Bar {

}

对象工厂

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;

@XmlRegistry
public class ObjectFactory {
    
    @XmlElementDecl(name = "bar")
    public JAXBElement<Bar> createBar(Bar bar) {
        return new JAXBElement<Bar>(new QName("bar"), Bar.class, bar);
    }

}

独立演示代码

以下是一些演示代码,您可以在Java SE中运行以验证一切是否正常:

演示

import java.util.*;
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.persistence.jaxb.JAXBContextProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        Map<String, Object> properties = new HashMap<String, Object>(2);
        properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
        properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
        JAXBContext jc = JAXBContext.newInstance(new Class[] {Foo.class, ObjectFactory.class}, properties);
        
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        StreamSource json = new StreamSource("src/forum19158056/input.json");
        Foo foo = unmarshaller.unmarshal(json, Foo.class).getValue();
        
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(foo, System.out);
    }

}

输入.json/输出

{"bar" : {} }

使用JAX-RS运行

下面的链接将帮助您在JAX-RS服务中利用MOXy:


1
我用MOXy成功地完成了它。虽然运行良好,但我必须在资源方法内以这种方式完成:JAXBContext context = JAXBContextFactory.createContext(new Class[] {ONIXMessage.class}, null); 我该如何从Jersey中获取eclipselink JAXBContext? - Artem Moskalev
2
在JavaEE 7中,是否有用于设置JAXBContext的非EclipseLink(即标准)属性? - Archimedes Trajano

9

由于你正在使用Jackson,因此可以使用JaxbAnnotationModule构造一个ObjectMapper并写出值。以下是将JAXB注释对象写入系统输出的一些代码。

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JaxbAnnotationModule());
        mapper.writeValue(System.out, jaxbObject);

这种方法也适用于Glassfish,因为它不使用容器提供的提供程序,这将导致类未找到异常,就像GLASSFISH-21141所说的那样。


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