列表中的 Cxf Wsdl2java 空条目消失
Posted
技术标签:
【中文标题】列表中的 Cxf Wsdl2java 空条目消失【英文标题】:Cxf Wsdl2java null entry in list disappear 【发布时间】:2016-03-21 08:35:34 【问题描述】:我用 cxf 创建了一个 web 服务客户端,带有 xew plugin 用于列表展开
问题是列表中的null
消失了。
例如:
我有一个带有字符串的 List<String>
和 null
-entry 的请求
当请求现在到达服务器时,它只包含字符串而不是 null
条目。所以示例列表中只有 2 个条目。
这里是 wsdl 的一个例子:
[..]
<!-- the request -->
<xsd:element name="createGroup">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="in0" nillable="true" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="1" name="in1" nillable="true" type="ns2:ArrayOfRole"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
[..]
<!-- the list which will be unwrapped -->
<xsd:complexType name="ArrayOfRole">
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0" name="Role" nillable="true" type="xsd:String"/>
</xsd:sequence>
</xsd:complexType>
我正在使用maven生成ws客户端
<properties>
<cxf.version>3.0.5</cxf.version>
<jaxbBasic.version>0.6.5</jaxbBasic.version>
</properties>
[..]
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>$cxf.version</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>src/main/java</sourceRoot>
<defaultOptions>
<bindingFiles>
<bindingFile>$basedir/jaxbBindings.xml</bindingFile>
<bindingFile>$basedir/jaxwsBindings.xml</bindingFile>
</bindingFiles>
<extraargs>
<!-- xew plugin for unwrapping list wrappers types NOTE: the args need to be over the others otherwise there are compilation errors -->
<extraarg>-xjc-Xxew</extraarg>
<extraarg>-xjc-Xxew:instantiate lazy</extraarg>
<!-- Generate toString, equals, hashcode methods -->
<extraarg>-xjc-Xts:style:de.company.tostring.CustomToStringStyle.DEFAULT</extraarg>
<extraarg>-xjc-Xequals</extraarg>
<extraarg>-xjc-XhashCode</extraarg>
</extraargs>
</defaultOptions>
<wsdlRoot>$ws.dirAbsolute</wsdlRoot>
<includes>
<include>*.wsdl</include>
</includes>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.apache.cxf.xjcplugins</groupId>
<artifactId>cxf-xjc-ts</artifactId>
<version>$cxf.version</version>
</dependency>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>$jaxbBasic.version</version>
</dependency>
<dependency>
<groupId>com.github.jaxb-xew-plugin</groupId>
<artifactId>jaxb-xew-plugin-fixed</artifactId> <!-- this is a custom version with a small modification see https://github.com/dmak/jaxb-xew-plugin/issues/44 -->
<version>1.7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-xjc</artifactId>
<version>2.2.11</version>
</dependency>
</dependencies>
</plugin>
jaxbBindings.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings version="2.1" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
<jaxb:globalBindings generateElementProperty="false"/>
</jaxb:bindings>
jaxwsBindings.xml
<jaxws:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
<jaxws:enableWrapperStyle>false</jaxws:enableWrapperStyle>
</jaxws:bindings>
一个示例请求:
final CreateGroup create = new CreateGroup();
create.setIn0("newgroup");
final List<String> roles = new ArrayList<String>();
roles.add("testrole");
roles.add(null);
roles.add("testrole2");
create.setIn1(roles);
final SamplePortType proxy = ..;
proxy.createGroup(create);
有没有办法让null
条目仍然存在于服务器端?
【问题讨论】:
您应该发布您的插件配置和示例请求。 @approxiblue 我已经添加了示例代码和我的配置。 可能为 ArrayOfRole 复杂类型设置 minOccurs="1" 有帮助吗? @cacert 不,故障来自 cxf 而不是 wsdl(我认为),轴一切正常。在这个例子中,用户可以没有组。所以 0 是正确的。 【参考方案1】:问题是jaxb-xew-plugin
生成的代码错过了nillable = true
对于列表的XmlElement
。
由插件生成:
@XmlElementWrapper(required = true, nillable = true)
@XmlElement(name = "Role", namespace = "http://www.***.com/example")
protected List<String> in1;
如果您尝试添加nillable=true
,它将起作用:
@XmlElementWrapper(required = true, nillable = true)
@XmlElement(name = "Role", namespace = "http://www.***.com/example", nillable = true)
protected List<String> in1;
所以插件似乎缺少包装值的 nillable
属性。
我认为问题在于this code part,其中XmlElement 被“提升”到外部元素,而nillable
属性被忽略了。
将以下代码 sn-p 添加到提到的代码部分将解决您的问题并生成工作代码:
JExpression nillable = getAnnotationMemberExpression(xmlElementOriginalAnnotation, "nillable");
if (nillable != null)
xmlElementAnnotation.param("nillable", nillable);
从 jaxb-xew-plugin 的 1.7 版 开始,此问题中讨论的问题已得到解决。 This issue 跟踪该案例,here 是发布版本。
【讨论】:
【参考方案2】:我对此不确定,但可能是 JAXB 绑定中的 generateElementProperty
可能导致问题吗?根据documentation,如果该属性设置为false,JAXB 将无法往返所有XML 文档。如果设置为 true,您将不得不处理 JAXBElement
类,但正如文档所述:
JAXBElement 类型在 unmarshal/marshal 操作中往返 name 元素的 XML 表示。
检查该页面中的示例,它可能会有所帮助。
【讨论】:
以上是关于列表中的 Cxf Wsdl2java 空条目消失的主要内容,如果未能解决你的问题,请参考以下文章