我试图从FpML(金融产品标记语言)4.5版本生成Java类。生成了大量代码,但我无法使用它。试图序列化一个简单的文档,我得到这个:
javax.xml.bind.MarshalException
- with linked exception: [com.sun.istack.SAXException2: unable
to marshal type
"org.fpml._2008.fpml_4_5.PositionReport"
as an element because it is missing an
@XmlRootElement annotation]
事实上,没有任何类具有@XmlRootElement注释,所以我可能做错了什么?我将xjc (JAXB 2.1)指向fpml-main-4-5。Xsd,然后包括所有类型。
万一我对这个问题的经验给了某人一个顿悟!时刻. .我补充如下:
在使用IntelliJ的“从实例文档中生成xsd”菜单选项生成的xsd文件时,我也遇到了这个问题。
当我接受该工具的所有默认值时,它生成了一个xsd文件,当与jaxb一起使用时,生成不带@XmlRootElement的java文件。在运行时,当我试图marshal时,我得到了与这个问题中讨论的相同的异常。
我回到IntellJ工具,在“设计类型”下拉菜单中看到了默认选项(当然我不明白…老实说,我现在也不知道)是:
设计类型:
“局部元素/全局复杂类型”
我把这个改为
“local文本/ types”
,现在它生成了一个(实质上)不同的xsd,当与jaxb一起使用时,生成了@XmlRootElement。我不能说我理解它的来龙去脉,但它对我很管用。
为了将其他人已经陈述或暗示的内容联系在一起,JAXB XJC决定是否将@XmlRootElement注释放在生成的类上的规则非常重要(请参阅本文)。
@XmlRootElement的存在是因为JAXB运行时需要某些信息才能封送/解封送给定对象,特别是XML元素名称和名称空间。你不能直接把任何旧对象传递给Marshaller。@XmlRootElement提供此信息。
然而,注释只是一种方便,JAXB并不需要它。另一种方法是使用JAXBElement包装器对象,它提供与@XmlRootElement相同的信息,但是以对象的形式,而不是注释的形式。
但是,JAXBElement对象构造起来很麻烦,因为您需要知道XML元素名称和名称空间,而业务逻辑通常不知道这些。
Thankfully, when XJC generates a class model, it also generates a class called ObjectFactory. This is partly there for backwards compatibility with JAXB v1, but it's also there as a place for XJC to put generated factory methods which create JAXBElement wrappers around your own objects. It handles the XML name and namespace for you, so you don't need to worry about it. You just need to look through the ObjectFactory methods (and for large schema, there can be hundreds of them) to find the one you need.
您可以使用如何在XSD中为基类型生成@XmlRootElement类中的绑定来修复此问题。
下面是Maven的一个示例
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.3.1</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaDirectory>src/main/resources/xsd</schemaDirectory>
<packageName>com.mycompany.schemas</packageName>
<bindingFiles>bindings.xjb</bindingFiles>
<extension>true</extension>
</configuration>
</plugin>
这是装订。XJB文件内容
<?xml version="1.0"?>
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc= "http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings schemaLocation="path/to/myschema.xsd" node="/xs:schema">
<jxb:globalBindings>
<xjc:simple/>
</jxb:globalBindings>
</jxb:bindings>
</jxb:bindings>