【问题标题】:Why is JAXB generateElementProperty=false not having the desired effect?为什么 JAXB generateElementProperty=false 没有达到预期的效果?
【发布时间】:2015-07-17 22:37:10
【问题描述】:

我正在使用以下绑定文件运行 wsimport 任务:

<jaxb:bindings version="2.1"
               xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema" >
    <jaxb:bindings>
        <jaxb:globalBindings generateElementProperty="false" typesafeEnumMaxMembers="2000" />
    </jaxb:bindings>
</jaxb:bindings>

但是,这会导致类使用JAXBElement&lt;String&gt; 而不是String,如下面的getUserSummaryOrTypeOrLogLevel() 所示

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ConfigSLMAction", propOrder = {
    "userSummaryOrTypeOrLogLevel"
})
public class ConfigSLMAction
    extends ConfigConfigBase
{

    @XmlElementRefs({
        @XmlElementRef(name = "UserSummary", type = JAXBElement.class, required = false),
        @XmlElementRef(name = "LogLevel", type = JAXBElement.class, required = false),
        @XmlElementRef(name = "Type", type = JAXBElement.class, required = false)
    })
    protected List<JAXBElement<String>> userSummaryOrTypeOrLogLevel;
    @XmlAttribute(name = "name")
    protected String name;
    @XmlAttribute(name = "local")
    protected Boolean local;
    @XmlAttribute(name = "intrinsic")
    protected Boolean intrinsic;
    @XmlAttribute(name = "read-only")
    protected Boolean readOnly;
    @XmlAttribute(name = "external")
    protected Boolean external;

    /**
     * Gets the value of the userSummaryOrTypeOrLogLevel property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a <CODE>set</CODE> method for the userSummaryOrTypeOrLogLevel property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getUserSummaryOrTypeOrLogLevel().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link JAXBElement }{@code <}{@link String }{@code >}
     * {@link JAXBElement }{@code <}{@link String }{@code >}
     * {@link JAXBElement }{@code <}{@link String }{@code >}
     * 
     * 
     */
    public List<JAXBElement<String>> getUserSummaryOrTypeOrLogLevel() {
        if (userSummaryOrTypeOrLogLevel == null) {
            userSummaryOrTypeOrLogLevel = new ArrayList<JAXBElement<String>>();
        }
        return this.userSummaryOrTypeOrLogLevel;
    }
    ...
    ...
    ...
}

生成此类的 xsd 文件中的条目如下:

<xsd:complexType name="ConfigSLMAction">
    <xsd:complexContent>
        <xsd:extension base="tns:ConfigConfigBase">
            <xsd:choice maxOccurs="unbounded">
                <xsd:element name="UserSummary" minOccurs="0" maxOccurs="1">
                    <xsd:simpleType>
                        <xsd:union memberTypes="tns:dmString tns:dmEmptyElement" />
                    </xsd:simpleType>
                </xsd:element>
                <xsd:element name="Type" minOccurs="1" maxOccurs="1">
                    <xsd:simpleType>
                        <xsd:union memberTypes="tns:dmSLMActionType tns:dmEmptyElement" />
                    </xsd:simpleType>
                </xsd:element>
                <xsd:element name="LogLevel" minOccurs="0" maxOccurs="1">
                    <xsd:simpleType>
                        <xsd:union memberTypes="tns:dmLogLevel tns:dmEmptyElement" />
                    </xsd:simpleType>
                </xsd:element>
            </xsd:choice>
            <xsd:attributeGroup ref="tns:ConfigAttributes" />
        </xsd:extension>
    </xsd:complexContent>
</xsd:complexType>

这是我的 pom 文件中的 Maven 插件

<plugin>
    <groupId>org.jvnet.jax-ws-commons</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>2.3</version>
    <executions>
        <execution>
            <id>wsimport-from-jdk</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>wsimport</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <wsdlFiles>
            <wsdlFile>${basedir}/src/main/resources/wsdl/xml-mgmt.wsdl</wsdlFile>
        </wsdlFiles>
        <bindingFiles>
            <bindingFile>${basedir}/src/main/resources/wsdl/bindings.xml</bindingFile>
        </bindingFiles>
        <keep>true</keep>
        <verbose>true</verbose>
        <extension>true</extension>
        <vmArgs>
            <vmArg>-Djavax.xml.accessExternalDTD=all</vmArg>
            <vmArg>-Djavax.xml.accessExternalSchema=all</vmArg>
        </vmArgs>
    </configuration>
</plugin>

谁能解释为什么会这样? 我希望使用 String 而不是 JAXBElement&lt;String&gt; 并且我在 SO 和其他地方找到的任何内容都表明 generateElementProperty=false 有效,但它不是。

【问题讨论】:

标签: java jaxb


【解决方案1】:

JAXBElement 是强制性的,如果有一个 xsd:choice 可以出现 foobar 元素并且它们是相同的类型。 一个简单的字符串不足以标记应编组的元素。

如果存在元素nillable="true"minOccurs="0",或者如果有两个具有相同名称xsd:complexType 的全局元素,则也需要JAXBElement

【讨论】:

    【解决方案2】:

    你可以尝试另一个插件来确保错误在 JAXB 中吗?在我们的项目中,我们正在使用:

            <plugin>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-codegen-plugin</artifactId>
                <executions>
                    <execution>
                        <id>generate-sources-ais</id>
                        <phase>generate-sources</phase>
                        <configuration>
                            <defaultOptions>
                                <bindingFiles>
                                    <bindingFile>${basedir}/src/main/resources/wsdl/binding/bindings.xml</bindingFile>
                                </bindingFiles>
                            </defaultOptions>
                            <sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>
                            <wsdlRoot>${basedir}/src/main/resources/wsdl</wsdlRoot>
                            <includes>
                                <include>**/*.wsdl</include>
                            </includes>
                        </configuration>
                        <goals>
                            <goal>wsdl2java</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
    

    它会像你期望的那样工作

    更新:

    你说得对,插件没问题。这是因为选择元素。可能与this重复

    【讨论】:

    • JAXBElement&lt;String&gt; 得到相同的输出,但我无法使用&lt;extraarg&gt;-xjc-Xinheritance&lt;/extraarg&gt;,因为插件引发了错误
    • 抱歉,您可能会错过这个参数。仅当您在 binding.xml 中使用继承时才需要它,然后您需要另一个依赖项。我会更新xml
    • 我还是把 arg 去掉了,仍然得到与使用 jaxws-maven-plugin 时相同的输出类
    • hm 你能提供整个 xml-mgmt.wsdl 和 xsd 所以可以试试吗?或至少整个 xsd 元素 ConfigSLMAction
    • 整个 XSD 元素都包含在问题中。恐怕我无法提供 WSDL,因为它受版权保护
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-21
    相关资源
    最近更新 更多