JAXB生成JAXBElement<String>而不是String。

40

我正在使用 Apache CXFcxf-codegen-plugin Maven 插件来从 WSDL 文件生成源代码。问题是我得到了生成的 JAXBElement<String>,而不是 String。我已经添加了 jaxb-bindings.xml 文件,它看起来像这样:

<jaxb:bindings version="2.1"
               xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
    <jaxb:globalBindings generateElementProperty="false"/>
</jaxb:bindings>

这应该可以防止JAXB生成JAXBElement<String>。但是它并没有起作用,我仍然得到了JAXBElement<String>而不是String

我的Maven插件看起来像这样:

<plugin>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-codegen-plugin</artifactId>
    <version>${cxf.runtime.version}</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-bindings-soap</artifactId>
            <version>${cxf.runtime.version}</version>
        </dependency>
    </dependencies>
    <executions>
        <execution>
            <id>generate-jaxb</id>
            <phase>generate-sources</phase>
            <configuration>
                <additionalJvmArgs>-Dfile.encoding=UTF8</additionalJvmArgs>
                <wsdlOptions>
                    <wsdlOption>
                        <wsdl>src/main/resources/wsdl/Cubiks.wsdl</wsdl>
                        <extraargs>
                            <extraarg>-b</extraarg>
                            <extraarg>${basedir}/jaxb-bindings.xml</extraarg>
                            <extraarg>-b</extraarg>
                            <extraarg>${basedir}/jaxws-bindings.xml</extraarg>
                            <extraarg>-exsh</extraarg>
                            <extraarg>true</extraarg>
                            <extraarg>-wsdlLocation</extraarg>
                            <extraarg></extraarg>
                        </extraargs>
                    </wsdlOption>
                    <wsdlOption>
                        <wsdl>src/main/resources/wsdl/CubiksCallBackService.wsdl</wsdl>
                        <extraargs>
                            <extraarg>-b</extraarg>
                            <extraarg>${basedir}/jaxws-bindings.xml</extraarg>
                            <extraarg>-b</extraarg>
                            <extraarg>${basedir}/jaxb-bindings.xml</extraarg>
                            <extraarg>-exsh</extraarg>
                            <extraarg>true</extraarg>
                            <extraarg>-p</extraarg>
                            <extraarg>com.cubiks.ws.callback</extraarg>
                            <extraarg>-wsdlLocation</extraarg>
                            <extraarg></extraarg>
                        </extraargs>
                    </wsdlOption>
                </wsdlOptions>
            </configuration>
            <goals>
                <goal>wsdl2java</goal>
            </goals>
        </execution>
    </executions>
</plugin>

CXF的版本是2.6.0。有人知道可能出了什么问题吗?

编辑

XSD非常庞大。这是生成JAXBElement<String>元素的部分。

  <xs:complexType name="ServiceResponse">
    <xs:sequence>
      <xs:element minOccurs="0" name="RequestStatus" type="tns:RequestStatus"/>
      <xs:element minOccurs="0" name="RequestStatusDescription" nillable="true" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element name="ServiceResponse" nillable="true" type="tns:ServiceResponse"/>

生成的源代码是:

@XmlElementRef(name = "RequestStatusDescription", namespace = "http://www.cubiksonline.com/2009/08/AssessmentProvider", type = JAXBElement.class)
protected JAXBElement<String> requestStatusDescription;

1
请提供WSDL文件,并且如果您有的话,也请提供XSD。 - popfalushi
6个回答

49

我需要做的是用另一个jaxb:bindingsjaxb:globalBindings包装起来。

<jaxb:bindings version="2.0"
               xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
    <jaxb:bindings>
        <jaxb:globalBindings generateElementProperty="false"/>
    </jaxb:bindings>
</jaxb:bindings>

现在一切都正常工作,不再生成JAXBElement<String>了。


很高兴报告这个解决方案在JDeveloper中也可以工作。只需创建一个XML文件,然后在向导的阶段将其传递给指定WSDL的URL/位置时即可。 - webuster
这在NetBeans 8.2中也有效。右键单击服务并选择“编辑Web服务属性”。然后转到“WSDL自定义”选项卡,在“外部绑定文件”下方添加此文件并重新生成。所有字符串都解析为字符串。谢谢! - Darrel K.
你把这段代码片段添加在哪里?@PauliusMatulionis - Reema

12

你不能同时使用nillable和minoccurs。移除minoccurs因为它对于字符串来说没有意义。


为什么我不能把它们放在一起?顺便说一下,wsdl文件是由客户提供的,我们没有创建它。我知道它们没有意义,但决定是否删除它们不是我的事。 - Paulius Matulionis
6
如果模式同时具有两个条件,那么你需要使用JAXBElement来区分XML元素缺失的情况(由minOccurs允许)和其存在但为xsi:nil的情况。如果模式只允许其中一个条件,则不需要JAXBElement,因为null属性值已足够。 - Ian Roberts
3
这篇文章很好地解释了它。 - Ian Roberts
一个字符串如果是可空的并且minoccurs=0是什么意思?如果满足这些条件,XML会是什么样子?无论如何,请查看此处以确保您正确使用绑定,其中有一个示例显示如何配置maven插件。您的绑定文件是正确的,但我怀疑如果您正确配置maven插件,它将起作用。由于您无法更改wsdl,因此这是您唯一的选择。 - ramsinb
很奇怪,我用jaxb:bindings包装了我的globalBindings,它居然起作用了。<jaxb:bindings version="2.0" xmlns:jaxb="" rel = "nofollow noreferrer">http://java.sun.com/xml/ns/jaxb"> jaxb:bindings <jaxb:globalBindings generateElementProperty="false"/> </jaxb:bindings> </jaxb:bindings>我仍然不明白为什么。 - Paulius Matulionis

6

我认为你需要在你的jaxb-binding.xml文件中添加以下内容:

<jaxb:bindings ... xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc">
    <jaxb:globalBindings generateElementProperty="false">
        <xjc:simple />
        <!-- ... -->
    </jaxb:globalBindings>
</jaxb:bindings>

我正在尝试添加它,但是出现了以下错误:com.sun.istack.SAXParseException2: "xjc:simple" 定制未与任何模式元素相关联。 - Paulius Matulionis
我已经成功地正确使用了<xjc:simple />,但仍然生成了JAXBElement<String>。 - Paulius Matulionis
2
好的,我现在已经检查了一个Web服务进行测试,是generateElementProperty="false"属性在我的情况下避免了JAXBElement包装器。对于噪音感到抱歉。 - Frank Pavageau

2

我在资源文件夹中创建了一个名为bindings.xml的文件,并添加了以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" elementFormDefault="qualified" attributeFormDefault="unqualified" jaxb:extensionBindingPrefixes="xjc" jaxb:version="2.1">
    <xs:annotation>
        <xs:appinfo>
            <jaxb:globalBindings>
                <xjc:simple /><!-- it did only work after adding this -->
            </jaxb:globalBindings>
        </xs:appinfo>
    </xs:annotation>
</xs:schema>

然后我在pom.xml中的cxf插件定义中提到了这个文件,如下所示:

<wsdlOptions>标签中,在<wsdlOption>中有wsdl文件的路径,我添加了一个<extraWsdlPath>标签,其中包含:

<bindingFiles> 
 <bindingFile> ${basedir}/src/min/resources/bindings.xml </bindingFile>  
</bindingFiles>

我的存根代码生成得非常漂亮,包含了实际类型。

0

我在我的WSDL模式中有重复的元素,这就是为什么CXF生成了JAXBElement而不是字符串。要小心。


0
当XSD中同时存在minouucrs=0nillable=true时,它会生成JAXBElement。为了避免这种情况,我们需要删除其中一个。
如果在从XSD模式生成POJO对象时使用generateElementProperty="false"属性,则它将像魔法一样工作。

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