jgoyer
jgoyer

Reputation: 73

Replace XML MessageFormatter in Spring PayloadValidatingInterceptor

I have banged my head against the wall for a couple of days on this one. We are using Spring web services 2.1.3.RELEASE and I have added a simple subclass of PayloadValidatingInterceptor to capture XSD schema validation errors.

Configuration:

<bean id="xsdValidationInterceptor" class="foo.bar.endpoint.interceptors.XSDValidatingInterceptor">
    <property name="schemas">
        <list> 
            <value>classpath:/xsd/requestName.xsd</value>
        </list>
    </property>
    <property name="validateRequest" value="true"/>
    <property name="validateResponse" value="true"/>
</bean>

XsdValidationInterceptor overrides handleRequestValidationErrors:

@Override
protected boolean handleRequestValidationErrors(
        MessageContext messageContext, SAXParseException[] errors)
        throws TransformerException  {
    if ( getAddValidationErrorDetail() ) {
        messageContext.setProperty(MessageContextConstants.KEY_SCHEMA_ERRORS, errors);
    }
    return true;
}

So far so good. This issue is the format of the messages that come back from the Xerces parser. Problem is, I want the field name and line/column numbers for where the error occurred without having to dig it out of a long String that is different for various errors. Seems like it should be simple but Spring does not seem to make this easy. And once the error appears at the handleRequestValidationErrors routine, the exception messages have been formatted already.

Specifically I would like to either replace the XMLErrorReporter or the MessageFormatter that the XMLErrorReporter uses in the schema validator that Spring creates. Xerces provides a standard property for replacing the error reporter; however, Spring does not make this easy. It uses a hard-coded JAXP factory called Jaxp13ValidatorFactory to create an XMLValidator object that essentially wraps creation of a Xerces validator at each request handling. XMLValidator does not allow setting of properties on the validator implementations it creates.

I have looked at custom configuration of Xerces as well as other possible hacks, and at this point the only thing I can think of is to override the handleRequest routine in the XsdValidationInterceptor to create my own validators that I can configure as needed.

Anybody have any better ideas?

This is the same question asked here, but unfortunately not answered:

How can I provide custom error messages using JAXP DocumentBuilder?

Upvotes: 1

Views: 468

Answers (1)

jgoyer
jgoyer

Reputation: 73

Ok so after doing some more research this problem is not Spring's fault. Seems to be a product of the way Sax parsing in Java evolved.

The basic architecture is Spring -> JAXP -> Parser Provider (Xerces).

The JAXP interface allows setting of features but does not provide the necessary control to replace the ErrorReporter component in the Xerces parser, nor to customize it. Customization would involve building a Xerces parser instance with a custom ErrorReporter component and overriding the Xerces implementation that is part of the JVM.

This is simply not a viable alternative when we are trying to deliver a product on top of a JVM in environments we may not control. Bottom line is that we have to live with the messages the way they are.

Upvotes: 1

Related Questions