Cxf Wsdl2java null entry in list disappear
Asked Answered
A

2

12

I've created a webservice client with cxf with the xew plugin for list unwrapping

The problem is that the null in the list disappear. E.g.:

I have an Request with a List<String> with Strings and a null-entry

When the request now arrives at the server it only contains the Strings not the null entry. So there are only 2 entries in the example list.

Here a example of the 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>

I'm using maven to generate the ws client

<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>

A sample request:

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);

Is there a way that the null entry is still be present at the serverside?

Abirritant answered 15/12, 2015 at 14:0 Comment(4)
You should post your plugin configuration and a sample request.Hamnet
@Hamnet I've added sample code and my configuration.Abirritant
May be setting minOccurs="1" for ArrayOfRole complex type can help ?Decency
@Decency no, the fault is from cxf not the wsdl (i think), with axis all works well. and as in this example the user could have no groups. so 0 is correct.Abirritant
E
3

The problem is that the jaxb-xew-plugin generates code that misses nillable = true for the XmlElement of the List.

Generated by the plugin:

@XmlElementWrapper(required = true, nillable = true)
@XmlElement(name = "Role", namespace = "http://www.stackoverflow.com/example")
protected List<String> in1;

If you try, with added nillable=true, it will work:

@XmlElementWrapper(required = true, nillable = true)
@XmlElement(name = "Role", namespace = "http://www.stackoverflow.com/example", nillable = true)
protected List<String> in1;

So it seems the plugin is missing the nillable attribute for wrapped values.

I think the problem lies in this code part, where the XmlElement is "lifted" to an outer element and the nillable attribute is left out.

Adding the following code snippet to the mentioned code part will solve your problem and generate working code:

JExpression nillable = getAnnotationMemberExpression(xmlElementOriginalAnnotation, "nillable");
if (nillable != null) {
    xmlElementAnnotation.param("nillable", nillable);
}

The problem discussed in this question is solved as of version 1.7 of the jaxb-xew-plugin. This issue keeps track of that case, here are the releases.

Etui answered 16/1, 2016 at 13:53 Comment(0)
Y
0

I'm not sure about this, but could it be that the generateElementProperty in the JAXB bindings may be causing the issue? According to the documentation, if that property is set to false, JAXB won't be able to roundtrip all XML documents. If set to true, you'll have to deal with JAXBElement class but, as the documentation says:

The JAXBElement type roundtrips the XML representation of name element across an unmarshal/marshal operation.

Check the examples in that page, it may help.

Yuhas answered 15/1, 2016 at 14:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.