JAXB2 - XJC - 生成的类上的 XmlElement.type 存在问题

JAXB2 - XJC - Problem with XmlElement.type on generated class

提问人:Cps 提问时间:8/22/2023 最后编辑:Cps 更新时间:8/22/2023 访问量:49

问:

顶级域名:我必须从 XSD 生成 Java 类,而“Main”对象的一个字段是另一个生成的类。该字段具有一个注释@XmlElement,该具有属性“type = Object.class”,同时具有字段 type = “SubObject”。这样,当我尝试将 XML 解组到 Java 对象中时,我会得到一个错误。

@XmlRootElement(name = "MainObject")
public class MainObject {
    @XmlElement(name = "SubObject", required = true, type = Object.class)
    protected SubObject subObject;
}

我已经尝试了 JAXB2 Maven 插件和 Apache-CXF-XJC 插件。在这两种情况下,我最终都得到了相同的结果。如果我手动从注释中删除类型属性,它可以工作。在这种情况下,如何生成没有 type 属性的类,或者使其成为 SubObject.class?

更多信息

在旧项目上工作的文件/配置:

POM.xml插件配置
<plugin>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-xjc-plugin</artifactId>
    <version>2.3.0</version>
    <configuration>
        <extensions>
            <extension>org.apache.cxf.xjcplugins:cxf-xjc-dv:2.3.0</extension>
        </extensions>
    </configuration>
    <executions>
        <execution>
            <id>generate-sources</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>xsdtojava</goal>
            </goals>
            <configuration>
                <sourceRoot>${project.build.sourceDirectory}/../generated/</sourceRoot>
                <xsdOptions>
                    <xsdOption>
                        <xsd>src/main/resources/xsd/subobject.xsd</xsd>
                        <packagename>org.acme.generated</packagename>
                    </xsdOption>                    
                    <xsdOption>
                        <xsd>src/main/resources/xsd/mainobject.xsd</xsd>
                        <packagename>org.acme.generated</packagename>
                        <bindingFile>src/main/resources/xsd/bindings.xjb</bindingFile>
                    </xsdOption>
                </xsdOptions>
            </configuration>
        </execution>
    </executions>
</plugin>
XJB 绑定文件
<bindings xmlns="http://java.sun.com/xml/ns/jaxb" xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.1">
    <bindings schemaLocation="mainobject.xsd" version="1.0">
        <bindings node="//xs:element[@name='SubObject']">
                <class ref="org.acme.generated.SubObject"/>
        </bindings>
    </bindings>
</bindings>
生成的 MainObject 类
@XmlRootElement(name = "MainObject")
public class MainObject {

    @XmlElement(name = "MainElement1", required = true)
    protected String mainElement1;
    @XmlElement(name = "MaintElement2")
    protected int maintElement2;
    @XmlElement(name = "SubObject", required = true)
    protected SubObject subObject;

现在,经过一番研究,我最终得到了以下较新插件的文件:

POM.xml插件配置
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
      <execution>
        <id>xjc</id>
        <goals>
          <goal>xjc</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <sources>src/main/resources/xsd</sources>
      <outputDirectory>src/main/generated</outputDirectory>
      <xjbSources>
        <xjbSource>src/main/resources/xjb</xjbSource>
      </xjbSources>
      <!-- The package of your generated sources -->
      <packageName>org.acme.generated</packageName>
    </configuration>
</plugin>
XJB 绑定文件
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
               jaxb:extensionBindingPrefixes="xjc"
               version="3.0">
    <jaxb:bindings schemaLocation="..\xsd\mainobject.xsd" version="1.0" node="//xsd:element[@name='SubObject']">
        <jaxb:property>
            <jaxb:baseType>
                <jaxb:javaType name="org.acme.generated.SubObject"/>
            </jaxb:baseType>
        </jaxb:property>
    </jaxb:bindings>
</jaxb:bindings>

生成的 MainObject 类
@XmlRootElement(name = "MainObject")
public class MainObject {

    @XmlElement(name = "MainElement1", required = true)
    protected String mainElement1;
    @XmlElement(name = "MaintElement2")
    protected int maintElement2;
    @XmlElement(name = "SubObject", required = true, type = Object.class)
    protected SubObject subObject;
生成的 SubObject 类
@XmlRootElement(name = "SubObject")
public class SubObject {

    @XmlElement(name = "SubElement1", required = true)
    protected String subElement1;
    @XmlElement(name = "SubElement2")
    protected int subElement2;

两个 xsd 文件保持不变,但生成的 MainObject 类现在在注释上具有 type 属性,值为 Object.class。当我尝试解组以下 XML 时:

<?xml version="1.0" encoding="utf-8"?>
<MainObject>
    <MainElement1>test1</MainElement1>
    <MainElement2>2</MainElement2>
    <SubObject>
        <SubElement1>test1</SubElement1>
        <SubElement2>2</SubElement2>
    </SubObject>
</MainObject>

我收到以下错误。但是,如果我从生成的类中手动删除 type = Object.class,则 unmarshal 可以完美运行。 为了添加更多信息,我还尝试使用apache-CXF-XJC插件(v4.0.0)的更新版本生成类,但我得到了相同的结果。java.lang.IllegalArgumentException: Can not set org.acme.generated.SubObject field org.acme.generated.MainObject.subObject to com.sun.org.apache.xerces.internal.dom.ElementNSImpl

有没有办法操作在注释@XmlElement上生成的类型属性?还是在将数据解组到对象中时忽略它?

java xml xsd maven-jaxb2-plugin cxf-xjc-plugin

评论

0赞 jdweng 8/22/2023
你的 SubObject 类在哪里?
0赞 Cps 8/22/2023
@jdweng刚刚用它更新了主帖子,一开始不得不删除它,因为系统将我的帖子标记为垃圾邮件。使用“新”插件和旧版本的 CXF 插件生成相同的类,因此这似乎不是问题。
0赞 LMC 8/22/2023
XSD 是什么样的?鼓励提出问题,以提供一个最小的可重复示例
0赞 jdweng 8/22/2023
尝试将 get/set 添加到您的所有属性中: protected String subElement1 { get; set;

答: 暂无答案