简体   繁体   中英

JAXB schema validation error with CXF - JAXBException occurred : cvc-elt.1: Cannot find the declaration of element

I have a REST service with CXF 3.0.1 which accepts an XML message in a HTTP POST payload. The XML payload is getting unmarshalled to an Object by JAXB .

I am trying to validate the XML through an XSD schema and I have configured the XSD in CXF but I keep getting the error below

JAXBException occurred : cvc-elt.1: Cannot find the declaration of element 'incident'.. cvc-elt.1: Cannot find the declaration of element 'incident'..

NOTE: incident is my root element

What I understand from that is that XSD is successfully registered by CXF but something is wrong in the JAXB side.

I have tried many possible solutions related to that error but none worked.

Any ideas

Thanks

Here is my configuration

Service

@Path("incident") 
public class CreateIncident { 
        @POST 
        @Consumes({ MediaType.APPLICATION_XML}) 
        public Response createIncident(Incident incident) { 
                        //code 
        } 
}

JAXB Object

@XmlRootElement(name = "incident") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Incident extends Event { 
        public Incident() { 
                super("incident"); 
        } 

        @XmlElement
        private String importProfile;

        @XmlElement
        private String eventTitle; 

        public String getImportProfile() { 
                return importProfile; 
        } 

        public void setImportProfile(String importProfile) { 
                this.importProfile = importProfile; 
        } 

        public String getEventTitle() {
                return eventTitle;
        }

        public void setEventTitle(String eventTitle) {
                this.eventTitle = eventTitle;
        }
}

Event:

public class Event {

    String eventType;

    public Event(String eventType) {
        this.eventType = eventType;
    }

    public String getEventType(){
        return eventType;
    }
}

My XSD

<?xml version="1.0" encoding="UTF-8"?>
<schema
    xmlns="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.ba.com/schema/BAassystWrapper/incident"
    elementFormDefault="qualified">
    <element name="incident">
        <complexType>
            <sequence>
                <element name="importProfile">
                    <simpleType>
                        <restriction base="string">
                            <minLength value="1"></minLength>
                            <maxLength value="254"></maxLength>
                        </restriction>
                    </simpleType>
                </element>
                <element name="eventTitle">
                    <simpleType>
                        <restriction base="string">
                            <minLength value="1"></minLength>
                            <maxLength value="890"></maxLength>
                        </restriction>
                    </simpleType>
                </element>
            </sequence>
        </complexType>
    </element>
</schema>

The XML that I pass

<incident>
    <importProfile>Test text</importProfile>
    <eventTitle>Test text</eventTitle>
</incident>

CXF Config

<jaxrs:server address="/">
                <jaxrs:schemaLocations>
                        <jaxrs:schemaLocation>classpath:xsd/incident.xsd</jaxrs:schemaLocation>
                </jaxrs:schemaLocations>
                <jaxrs:serviceBeans>
                        <bean class="com.ba.sysman.services.events.CreateIncident"></bean>
                </jaxrs:serviceBeans>
                <jaxrs:features>
                        <cxf:logging/>
                </jaxrs:features>
</jaxrs:server>

THe root elements need to be namespace qualified. Thus, the incoming XML needs to be something like:

<incident xmlns="http://www.ba.com/.......">

Since you have not defined namesapce in @XmlRootElement remove the namespace from the input.

@XmlRootElement(name = "incident") 
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({Event.class}) 
public class Incident extends Event { 
        public Incident() { 
                super("incident"); 
        }

    //fields, getters and setters
}

And in event class add default constructor

public Event(){

}

However its better to use xjc plugin and wadl2java/wsdl2java plugin and generate jaxb classes from xsd, which would save lots of time when you change xsd frequently and also use xmlns

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM