Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring's PayloadValidatingInterceptor evaluates XML (uncorrect) invalid

I'm developing in a Spring project using Sping-WS (2.1).

Using the PayloadValidatingInterceptor the messages we're sending via Spring Mock or soapUI are rated invalid.

We checked the XSD several times and we're sure, the data and the schema are correct. I implemented two test cases inside our SpringJUnit4ClassRunner using the springframework.xml-validator engine and javax.xml.validation classes to validate the payload outside of the WS against the schema. There they're valid.

Does anybody knows a reason why the validation inside the WS behaves different to the manual validation?

like image 324
steyze Avatar asked Mar 26 '26 03:03

steyze


1 Answers

I've had some problems with the PayloadValidatingInterceptor as well. I created a simple alternative, based on what I read here. Sometimes the interceptor will not work as expected - making it StringReader-based instead of String-based solved my problems. Perhaps this will help solving your issue as well!


To detail the solution given there, you can replace the interceptor with a proxy class like this:

import java.io.StringReader;
import java.io.StringWriter;

import org.springframework.ws.client.WebServiceTransformerException;
import org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.springframework.ws.WebServiceMessage;

public class PayloadValidatingInterceptorWithSourceFix extends
        PayloadValidatingInterceptor {

    @Override
    protected Source getValidationRequestSource(WebServiceMessage request) {
        return transformSourceToStreamSourceWithStringReader(request
                .getPayloadSource());
    }

    @Override
    protected Source getValidationResponseSource(WebServiceMessage response) {
        return transformSourceToStreamSourceWithStringReader(response
                .getPayloadSource());
    }

    Source transformSourceToStreamSourceWithStringReader(
            Source notValidatableSource) {
        final Source source;
        try {
            Transformer transformer = TransformerFactory.newInstance()
                    .newTransformer();

            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
                    "yes");
            transformer.setOutputProperty(OutputKeys.INDENT, "no");
            StringWriter writer = new StringWriter();
            transformer.transform(notValidatableSource,
                    new StreamResult(writer));

            String transformed = writer.toString();
            StringReader reader = new StringReader(transformed);
            source = new StreamSource(reader);

        } catch (TransformerException transformerException) {
            throw new WebServiceTransformerException(
                    "Could not convert the source to a StreamSource with a StringReader",
                    transformerException);
        }

        return source;
    }
}

and use it like

<bean id="payloadValidatingInterceptorWithSourceFix"
    class="path.to.your.PayloadValidatingInterceptorWithSourceFix">
    <property name="schema"
        value="file:WebContent/WEB-INF/schemas/account-balance-service.xsd" />
    <property name="validateRequest" value="true" />
    <property name="validateResponse" value="true" />
</bean>
like image 176
evandongen Avatar answered Mar 27 '26 22:03

evandongen