Server-Side XML Validation with CXF Webservice
Asked Answered
A

1

15

I'm working on an Apache CXF webservice (using JAX-WS, over SOAP). The service itself is pretty simple: receive a request, insert the request into a database, and return whether the insert was successful. I'd like to rely on XML validation to enforce a number of constraints on the request.

So, my question. How do I return detailed validation errors to a client of my service? I've turned validation on server-side by configuring my endpoint.

<jaxws:endpoint id="someEndpoint" implementor="#someImpl" address="/impl">
    <jaxws:properties>
        <!-- This entry should- ideally- enable JAXB validation
        on the server-side of our web service. -->
        <entry key="schema-validation-enabled" value="true" />
    </jaxws:properties>
</jaxws:endpoint>

I've explored using interceptors (eg BareInInterceptor) on the server, and somehow catching SAXParseExceptions to wrap them and send them along to the client. This approach seems a bit complicated, but I need to somehow give clients a line number if their XML is invalid. Should I go with interceptors to expose the exceptions?

I'm not very experienced with this technology stack, and just getting in to web services- any pointers you guys can give me would be really appreciated.

Asbury answered 3/2, 2010 at 20:3 Comment(2)
Bear in mind that if the XML in your request is being generated by a SOAP client application (such as you'd get from generating stubs from your own service), your line number is likely to be 1 very often (since many clients will simply generate a 1-very-long-line XML document).Berryman
@Ian McLaird: this is valid comments, on the other hand, when application is tested by testers, they use better formatting and this will help themFennel
C
28

You can override validation error messages, inserting a line number, by using a custom ValidationEventHandler:

package example;

import javax.xml.bind.ValidationEvent;
import javax.xml.bind.helpers.DefaultValidationEventHandler;

public class MyValidationEventHandler extends DefaultValidationEventHandler {    
    @Override
    public boolean handleEvent(ValidationEvent event) {
        if (event.getSeverity() == ValidationEvent.WARNING) {
            return super.handleEvent(event);
        } else {
            throw new RuntimeException(event.getMessage()
                + " [line:"+event.getLocator().getLineNumber()+"]");
        }
    }
}

If you configure your endpoint to use this handler:

<jaxws:endpoint id="someEndpoint" implementor="#someImpl" address="/impl">
    <jaxws:properties>
        <entry key="schema-validation-enabled" value="true" />
        <entry key="jaxb-validation-event-handler">
            <bean class="example.MyValidationEventHandler" />
        </entry>
    </jaxws:properties>
</jaxws:endpoint>

Then you will get SOAP faults that look like this:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <soap:Fault>
            <faultcode>soap:Client</faultcode>
            <faultstring>Unmarshalling Error: Not a number: xyz [line: 6]</faultstring>
        </soap:Fault>
    </soap:Body>
</soap:Envelope>

The jaxb-validation-event-handler property was only added to CXF pretty recently, so you need to make sure you're using the latest version - I tested this with 2.2.5.

Coiffure answered 5/2, 2010 at 23:46 Comment(4)
I'll give this a try in the morning!Asbury
It seems, that this approach is not properly working for CXF 2.2.9. This will still return line number for case, when wrong date value specified, but line number will be wrong. For other exceptions, f.e. broken restriction for string length this won't append line number, and initil SAXParseException will be returned. So, as I understand, there is one way -- handling faults and reparsing document, when SAXParseExceptions received.Recreate
Hi, I tried this and the code enters the section where the RuntimeException is thrown I am able to log it on a server side, however the message does not get to a client, I use soapUI , only standard validation fault is return but the line number is not appeneded.Houphouetboigny
"schema-validation-enabled" true, is not working for cxf 3.0.4. Can you please suggest equivalent config.Caulicle

© 2022 - 2024 — McMap. All rights reserved.