CXF: 3.1.10
JDK 1.8
Tomcat 8.0.18
 
I have a situation with a WSDL that is very terse and the resultant stubs, 
though they compile in the WSDL’s JAR project, cannot be used in the main 
application’s WAR project.
 
The WSDL’s single message structure is like this:
 
Message
----(2 string attributes)
--Header
----(4 string attributes)
--Body
----(sequence)
------Request
--------(xsd:any)
------Response
--------(xsd:any)
 
The first problem was that the classes weren’t serializable. So I started 
building a binding file to add that aspect. That part was easy.
 
But the Header, Body, Response, and Request classes are generated as internal 
static sub-classes of Message (because in the WSDL schema section, they are all 
internal to the Message).
 
When CXF tries to marshal a call to the service, an exception occurs saying:
 
org.apache.cxf.interceptor.Fault: Marshalling Error: unable to marshal type 
"a.b.Message$Header" as an element because it is missing an @XmlRootElement 
annotation
 
The Message class has an @XmlRootElement annotation, but not the subclasses. 
The class looks like this:
 
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "content"
})
@XmlRootElement(name = "TLETSMessage")
public class TLETSMessage
    implements Serializable
{
 
    private final static long serialVersionUID = 1L;
    @XmlElementRefs({
        @XmlElementRef(name = "Header", type = JAXBElement.class),
        @XmlElementRef(name = "Body", type = JAXBElement.class)
    })
    @XmlMixed
    protected List<Serializable> content;
    @XmlAttribute(name = "key", required = true)
    protected String key;
    @XmlAttribute(name = "version", required = true)
    protected String version;
 
    public List<Serializable> getContent() {
        if (content == null) {
            content = new ArrayList<Serializable>();
        }
        return this.content;
    }
…
 
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "request",
        "response"
    })
    public static class Body
        implements Serializable
    {
 
        private final static long serialVersionUID = 1L;
        @XmlElement(name = "Request", required = true)
        protected TLETSMessage.Body.Request request;
        @XmlElement(name = "Response")
        protected TLETSMessage.Body.Response response;
 
        public TLETSMessage.Body.Request getRequest() {
            return request;
        }
 
        public void setRequest(TLETSMessage.Body.Request value) {
            this.request = value;
        }
 
        public TLETSMessage.Body.Response getResponse() {
            return response;
        }
…
 
I then added entries to the binding file and pom.xml to add the @XmlRootElement 
annotation to the Header and Body classes:
 
<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb 
<http://java.sun.com/xml/ns/jaxb>"
    xmlns:annox="http://annox.dev.java.net <http://annox.dev.java.net/>" 
extensionBindingPrefixes="xjc annox"
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc 
<http://java.sun.com/xml/ns/jaxb/xjc>"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema 
<http://www.w3.org/2001/XMLSchema>"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/ 
<http://schemas.xmlsoap.org/wsdl/>" version="2.1"
> 
    <globalBindings>
        <serializable uid="1" />
    </globalBindings>
 
    <bindings schemaLocation="META-INF/DMVService.wsdl#types1"
        node="/xsd:schema"
    >
 
   <!-- Annotate the following classes with XmlRootElement -->
        <bindings node="//xsd:element[@name='Header']">
            <annox:annotate>
                <annox:annotate
                    annox:class="javax.xml.bind.annotation.XmlRootElement"
                    name="Header" />
            </annox:annotate>
        </bindings>
 
        <bindings node="//xsd:element[@name='Body']">
            <annox:annotate>
                <annox:annotate
                    annox:class="javax.xml.bind.annotation.XmlRootElement"
                    name="Body" />
            </annox:annotate>
        </bindings>
 
    </bindings>
 
</bindings>
 
And I thought I had it done, but what is generated is wrong, the annotation is 
put on a method that isn’t explicit in the WSDL so I guess a generic one was 
generated.
 
    @XmlRootElement(name = "Body")
    public List<Serializable> getContent() {
        if (content == null) {
            content = new ArrayList<Serializable>();
        }
        return this.content;
    }
 
But not where I hoped it would be:
 
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "request",
        "response"
    })
    public static class Body
        implements Serializable
    {
 
Here is an extract from the WSDL, hopefully someone can tell me how to fix the 
binding?
 
    <wsdl:types>
        <xsd:schema xmlns="http://www.openfox.com <http://www.openfox.com/>"
            targetNamespace="http://www.openfox.com <http://www.openfox.com/>"
        >
<!-- TLETSMessage -->
            <xsd:element name="TLETSMessage">
                <xsd:complexType mixed="true">
                    <xsd:sequence>
      <!-- Header -->
                        <xsd:element name="Header">
                            <xsd:complexType>
                                <xsd:sequence>
        <!-- Initiator -->
                                    <xsd:element name="Initiator">
                                        <xsd:simpleType>
                                            <xsd:restriction
                                                base="xsd:string"
                                            >
                                                <xsd:maxLength
                                                    value="9"
                                                ></xsd:maxLength>
                                                <xsd:minLength
                                                    value="4"
                                                ></xsd:minLength>
                                            </xsd:restriction>
                                        </xsd:simpleType>
                                    </xsd:element>
 
        <!-- Destination -->
                                    <xsd:element name="Destination">
                                        <xsd:simpleType>
                                            <xsd:restriction
                                                base="xsd:string"
                                            >
                                                <xsd:maxLength
                                                    value="9"
                                                ></xsd:maxLength>
                                                <xsd:minLength
                                                    value="2"
                                                ></xsd:minLength>
                                            </xsd:restriction>
                                        </xsd:simpleType>
                                    </xsd:element>
 
        <!-- ControlField -->
                                    <xsd:element name="ControlField">
                                        <xsd:simpleType>
                                            <xsd:restriction
                                                base="xsd:string"
                                            >
            <!--xsd:pattern value="\d{6}"/-->
                                                <xsd:length
                                                    value="10"
                                                ></xsd:length>
                                            </xsd:restriction>
                                        </xsd:simpleType>
                                    </xsd:element>
 
        <!-- UserId -->
                                    <xsd:element name="UserId">
                                        <xsd:simpleType>
                                            <xsd:restriction
                                                base="xsd:string"
                                            >
                                                <xsd:length 
value="7"></xsd:length>
                                            </xsd:restriction>
                                        </xsd:simpleType>
                                    </xsd:element>
                                </xsd:sequence>
                            </xsd:complexType>
                        </xsd:element> <!-- end Header -->
 
      <!-- Body -->
                        <xsd:element name="Body">
                            <xsd:complexType>
                                <xsd:sequence>
                                    <xsd:element name="Request">
                                        <xsd:complexType>
                                            <xsd:sequence>
                                                <xsd:any></xsd:any>
                                            </xsd:sequence>
                                        </xsd:complexType>
                                    </xsd:element>
                                    <xsd:element name="Response"
                                        minOccurs="0" maxOccurs="1"
                                    >
                                        <xsd:complexType>
                                            <xsd:sequence>
                                                <xsd:any></xsd:any>
                                            </xsd:sequence>
                                        </xsd:complexType>
                                    </xsd:element>
                                </xsd:sequence>
                            </xsd:complexType>
                        </xsd:element>
                    </xsd:sequence>
     <!-- TLETSMessage attributes -->
                    <xsd:attribute name="key" type="xsd:string"
                        use="required"
                    ></xsd:attribute>
                    <xsd:attribute name="version"
                        type="xsd:string" use="required"
                    ></xsd:attribute>
                </xsd:complexType>
            </xsd:element> <!-- end TLETSMessage -->
        </xsd:schema>

Reply via email to