markus
markus

Reputation: 83

CXF validation custom handler

I'm creating a webservice with cxf in the following way:

<cxf:cxfEndpoint id=XXXEndpoint"
                 serviceClass="com.Sth"
                 address="${webservices.url}/XXX"
                 wsdlURL="${wsdl.address}/services/XXX.wsdl"
                 endpointName="m:XXXPort"
                 serviceName="m:XXXService"
                 xmlns:m="http://com.sth/XXX">
    <cxf:properties>
        <entry key="schema-validation-enabled" value="true" />
    </cxf:properties>
</cxf:cxfEndpoint>

it works perfectly, also added schema validation. I cannot add a custom validation handler. How can I do that?

Upvotes: 1

Views: 9809

Answers (1)

Dawid Pytel
Dawid Pytel

Reputation: 2810

I'm not sure what you mean by custom validation handler.

If you want to change validation error handling you can create class implementing javax.xml.bind.ValidationEventHandler

For instance I used this approach to prevent JAXB from throwing exception on the first encountered error. My custom event handler collected all non-fatal validation errors and thrown appropriate exception after validating whole incoming message.

Sample use of ValidationEventHandler

In order to use your custom validation event handler you should add jaxb-validation-event-handler property:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
        http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd">


    <jaxws:endpoint id="HTTPEndpoint"
        implementor="org.dpytel.servicemix.cxf.wsdlfirst.PersonImpl" address="/PersonService"
        wsdlLocation="wsdl/person.wsdl" endpointName="e:soap" serviceName="s:PersonService"
        xmlns:e="http://servicemix.apache.org/samples/wsdl-first" xmlns:s="http://servicemix.apache.org/samples/wsdl-first">
        <jaxws:properties>
            <entry key="schema-validation-enabled" value="true" />
            <entry key="jaxb-validation-event-handler">
                <bean class="org.dpytel.servicemix.cxf.wsdlfirst.MyCustomHandler"></bean>
            </entry>
        </jaxws:properties>
    </jaxws:endpoint>

</beans>

Camel CXF endpoint configuration:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://camel.apache.org/schema/cxf"
    xsi:schemaLocation="
         http://www.springframework.org/schema/beans 
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
         http://camel.apache.org/schema/cxf 
         http://camel.apache.org/schema/cxf/camel-cxf.xsd">

    <cxf:cxfEndpoint id="personEndpoint" address="/person"
        serviceClass="org.apache.servicemix.samples.wsdl_first.Person"
        wsdlURL="wsdl/person.wsdl">
        <cxf:properties>
            <entry key="schema-validation-enabled" value="true" />
            <entry key="jaxb-validation-event-handler">
                <bean class="org.dpytel.servicemix.camel.MyCustomHandler" />
            </entry>
        </cxf:properties>
    </cxf:cxfEndpoint>

</beans>

Example handler that disables validation error and just logs the validation message:

import java.util.logging.Logger;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;

public class MyCustomHandler implements ValidationEventHandler {

    private Logger logger = Logger.getLogger(this.getClass().getCanonicalName());

    public boolean handleEvent(ValidationEvent event) {
        logger.severe("Error: " + event.getMessage());
        return true;
    }

}

Please note that some validation errors will cause CXF to skip calling your handler (See details of DataReaderImpl.WSUIDValidationHandler.handleEvent(...)). Your handler will be skipped if error message contains ":Id" string, or is one of the following errors:

  • cvc-type.3.1.1
  • cvc-type.3.2.2
  • cvc-complex-type.3.1.1
  • cvc-complex-type.3.2.2

(frankly it seems like a dirty hack in CXF and if it is a problem for you I would create a bug for CXF team).

If you want more error handling customization you should probably consider writing your own Interceptor. Probably the best phase to perform such validation would be one of (PRE/USER/POST)_LOGICAL.

Upvotes: 4

Related Questions