【问题标题】:Proper way of creating JAXB objects创建 JAXB 对象的正确方法
【发布时间】:2014-01-21 07:46:07
【问题描述】:

我注意到由 jaxb 编译器 xjc 生成的 ObjectFactory 类。我读到了一些关于它的目的。

我想知道创建 jaxb 对象的正确方法是什么,因为我根本不需要这个类。我是否应该始终使用ObjectFactory,即使是在琐碎的情况下,还是可以通过普通构造函数构造对象(什么肯定可以)?

编辑:添加示例:

我需要创建IpAddress的实例

这是工厂方法:

  public IpAddress createIpAddress() {
        return new IpAddress();
    }

是不是更好IpAddress ia = new IpAddress()

IpAddress ia = objectFactory.createIpdAddress()

【问题讨论】:

标签: java jaxb


【解决方案1】:

如果您使用ObjectFactory 创建域对象的实例或仅使用JAXB 2 (JSR-222) 中的零参数构造函数,则创建的实例没有区别。在 JAXB 1 (JSR-031) 而不是 POJO 中,JAXB impls 创建了与供应商特定的 impl 类的接口,当时需要 ObjectFactory 创建实例。

有时需要将域对象包装在JAXBElement 的实例中,ObjectFactory 包含执行此操作的有用方法(请参阅:http://blog.bdoughan.com/2012/07/jaxb-and-root-elements.html)。

ObjectFactory 最终是 JAXB 所包含的元数据所必需的。 JAXB 在处理类时会遍历传递依赖。在 ObjectFactory 上使用 create 方法提供了一个类,JAXB 可以使用该类来处理整个模型的元数据。


更新

好的。那么从最佳实践角度来看,正确的方法是什么? (见我的 请举例)

这真的取决于。我个人更喜欢使用构造函数。我在下面有一个示例来演示这两种方法。

XML 架构

下面是我用来创建 Java 模型的 XML Schema。

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" >
    <xs:element name="root" type="root"/>
    <xs:complexType name="root">
        <xs:sequence>
            <xs:element name="foo">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="bar" type="xs:string"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

演示代码

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

public class Demo {

    public static void main(String[] args) {
        // Using Constructors
        Root.Foo foo1 = new Root.Foo();
        foo1.setBar("Hello");
        Root root1 = new Root();
        root1.setFoo(foo1);
        JAXBElement<Root> jaxbElement1 = new JAXBElement<Root>(new QName("root"), Root.class, root1);


        // Using ObjectFactory
        ObjectFactory objectFactory = new ObjectFactory();
        Root.Foo foo2 = objectFactory.createRootFoo();
        foo2.setBar("World");
        Root root2 = objectFactory.createRoot();
        root2.setFoo(foo2);
        JAXBElement<Root> jaxbElement2 = objectFactory.createRoot(root2);
    }

}

【讨论】:

  • 好的。那么从最佳实践角度来看,正确的方法是什么? (请参阅我的示例)
  • @LeNoob - 是的,两种方法都可以。
【解决方案2】:

JAXB 使用ObjectFactory 来标识要绑定的类,例如

    JAXBContext ctx = JAXBContext.newInstance("test"); <-- test is package
    Marshaller m = ctx.createMarshaller();
    m.marshal(new X(), System.out);  <-- X is test package

抛出

javax.xml.bind.JAXBException: "test" doesnt contain ObjectFactory.class or jaxb.index

但是

JAXBContext ctx = JAXBContext.newInstance(X.class);
...

工作正常,因为我们将 X 显式加载到 JAXBCOntext

【讨论】:

  • 我的问题与我添加到问题中的示例有关。
猜你喜欢
  • 1970-01-01
  • 2017-11-01
  • 1970-01-01
  • 2021-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-22
相关资源
最近更新 更多