SWS-242 - Allow for custom ErrorHandler in PayloadValidatingInterceptor
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2005-2010 the original author or authors.
|
||||
* Copyright 2005-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -31,6 +31,7 @@ import org.springframework.ws.server.EndpointInterceptor;
|
||||
import org.springframework.ws.soap.SoapFault;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.xml.transform.TransformerObjectSupport;
|
||||
import org.springframework.xml.validation.ValidationErrorHandler;
|
||||
import org.springframework.xml.validation.XmlValidator;
|
||||
import org.springframework.xml.validation.XmlValidatorFactory;
|
||||
import org.springframework.xml.xsd.XsdSchema;
|
||||
@@ -65,6 +66,8 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
|
||||
|
||||
private XmlValidator validator;
|
||||
|
||||
private ValidationErrorHandler errorHandler;
|
||||
|
||||
public String getSchemaLanguage() {
|
||||
return schemaLanguage;
|
||||
}
|
||||
@@ -131,6 +134,15 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
|
||||
this.validator = schemaCollection.createValidator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the error handler to use for validation. If not set, a default error handler will be used.
|
||||
*
|
||||
* @param errorHandler the error handler.
|
||||
*/
|
||||
public void setErrorHandler(ValidationErrorHandler errorHandler) {
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
/** Indicates whether the request should be validated against the schema. Default is <code>true</code>. */
|
||||
public void setValidateRequest(boolean validateRequest) {
|
||||
this.validateRequest = validateRequest;
|
||||
@@ -171,7 +183,7 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
|
||||
if (validateRequest) {
|
||||
Source requestSource = getValidationRequestSource(messageContext.getRequest());
|
||||
if (requestSource != null) {
|
||||
SAXParseException[] errors = validator.validate(requestSource);
|
||||
SAXParseException[] errors = validator.validate(requestSource, errorHandler);
|
||||
if (!ObjectUtils.isEmpty(errors)) {
|
||||
return handleRequestValidationErrors(messageContext, errors);
|
||||
}
|
||||
@@ -213,7 +225,7 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
|
||||
if (validateResponse) {
|
||||
Source responseSource = getValidationResponseSource(messageContext.getResponse());
|
||||
if (responseSource != null) {
|
||||
SAXParseException[] errors = validator.validate(responseSource);
|
||||
SAXParseException[] errors = validator.validate(responseSource, errorHandler);
|
||||
if (!ObjectUtils.isEmpty(errors)) {
|
||||
return handleResponseValidationErrors(messageContext, errors);
|
||||
}
|
||||
@@ -227,11 +239,11 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
|
||||
|
||||
/**
|
||||
* Template method that is called when the response message contains validation errors. Default implementation logs
|
||||
* all errors, and returns <code>false</code>, i.e. do not cot continue to process the respone interceptor chain.
|
||||
* all errors, and returns <code>false</code>, i.e. do not cot continue to process the response interceptor chain.
|
||||
*
|
||||
* @param messageContext the message context
|
||||
* @param errors the validation errors
|
||||
* @return <code>true</code> to continue the reponse interceptor chain, <code>false</code> (the default) otherwise
|
||||
* @return <code>true</code> to continue the response interceptor chain, <code>false</code> (the default) otherwise
|
||||
*/
|
||||
protected boolean handleResponseValidationErrors(MessageContext messageContext, SAXParseException[] errors) {
|
||||
for (SAXParseException error : errors) {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2005-2010 the original author or authors.
|
||||
* Copyright 2005-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -44,11 +44,13 @@ import org.springframework.ws.soap.soap11.Soap11Fault;
|
||||
import org.springframework.ws.soap.soap12.Soap12Fault;
|
||||
import org.springframework.ws.transport.MockTransportInputStream;
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
import org.springframework.xml.validation.ValidationErrorHandler;
|
||||
import org.springframework.xml.xsd.SimpleXsdSchema;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
import org.xml.sax.helpers.LocatorImpl;
|
||||
|
||||
@@ -95,7 +97,7 @@ public class PayloadValidatingInterceptorTest {
|
||||
|
||||
@Test
|
||||
public void testHandleInvalidRequestSoap11() throws Exception {
|
||||
SoapMessage invalidMessage = (SoapMessage) soap11Factory.createWebServiceMessage();
|
||||
SoapMessage invalidMessage = soap11Factory.createWebServiceMessage();
|
||||
InputStream inputStream = getClass().getResourceAsStream(INVALID_MESSAGE);
|
||||
transformer.transform(new StreamSource(inputStream), invalidMessage.getPayloadResult());
|
||||
context = new DefaultMessageContext(invalidMessage, soap11Factory);
|
||||
@@ -115,7 +117,7 @@ public class PayloadValidatingInterceptorTest {
|
||||
|
||||
@Test
|
||||
public void testHandleInvalidRequestSoap12() throws Exception {
|
||||
SoapMessage invalidMessage = (SoapMessage) soap12Factory.createWebServiceMessage();
|
||||
SoapMessage invalidMessage = soap12Factory.createWebServiceMessage();
|
||||
InputStream inputStream = getClass().getResourceAsStream(INVALID_MESSAGE);
|
||||
transformer.transform(new StreamSource(inputStream), invalidMessage.getPayloadResult());
|
||||
context = new DefaultMessageContext(invalidMessage, soap12Factory);
|
||||
@@ -365,4 +367,31 @@ public class PayloadValidatingInterceptorTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customErrorHandler() throws Exception {
|
||||
ValidationErrorHandler errorHandler = new ValidationErrorHandler() {
|
||||
public SAXParseException[] getErrors() {
|
||||
return new SAXParseException[0];
|
||||
}
|
||||
|
||||
public void warning(SAXParseException exception) throws SAXException {
|
||||
}
|
||||
|
||||
public void error(SAXParseException exception) throws SAXException {
|
||||
}
|
||||
|
||||
public void fatalError(SAXParseException exception) throws SAXException {
|
||||
}
|
||||
};
|
||||
interceptor.setErrorHandler(errorHandler);
|
||||
SoapMessage invalidMessage = soap11Factory.createWebServiceMessage();
|
||||
InputStream inputStream = getClass().getResourceAsStream(INVALID_MESSAGE);
|
||||
transformer.transform(new StreamSource(inputStream), invalidMessage.getPayloadResult());
|
||||
context = new DefaultMessageContext(invalidMessage, soap11Factory);
|
||||
|
||||
boolean result = interceptor.handleRequest(context, null);
|
||||
Assert.assertTrue("Invalid response from interceptor", result);
|
||||
Assert.assertFalse("Context has response", context.hasResponse());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2005-2010 the original author or authors.
|
||||
* Copyright 2005-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -46,7 +46,9 @@ import org.xml.sax.helpers.DefaultHandler;
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.0.0
|
||||
* @deprecated in favor of {@link Jaxp13ValidatorFactory}
|
||||
*/
|
||||
@Deprecated
|
||||
abstract class Jaxp10ValidatorFactory {
|
||||
|
||||
private static final String SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
|
||||
@@ -80,9 +82,14 @@ abstract class Jaxp10ValidatorFactory {
|
||||
parserFactory.setValidating(true);
|
||||
}
|
||||
|
||||
public SAXParseException[] validate(Source source, ValidationErrorHandler errorHandler)
|
||||
throws IOException {
|
||||
return validate(source);
|
||||
}
|
||||
|
||||
public SAXParseException[] validate(Source source) throws IOException {
|
||||
SAXParser parser = createSAXParser();
|
||||
ValidationErrorHandler errorHandler = new ValidationErrorHandler();
|
||||
DefaultValidationErrorHandler errorHandler = new DefaultValidationErrorHandler();
|
||||
try {
|
||||
if (source instanceof SAXSource) {
|
||||
validateSAXSource((SAXSource) source, parser, errorHandler);
|
||||
@@ -104,7 +111,7 @@ abstract class Jaxp10ValidatorFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private void validateDOMSource(DOMSource domSource, SAXParser parser, ValidationErrorHandler errorHandler)
|
||||
private void validateDOMSource(DOMSource domSource, SAXParser parser, DefaultValidationErrorHandler errorHandler)
|
||||
throws IOException, SAXException {
|
||||
try {
|
||||
// Sadly, JAXP 1.0 DOM doesn't implement DOM level 3, so we cannot use Document.normalizeDocument()
|
||||
@@ -123,7 +130,7 @@ abstract class Jaxp10ValidatorFactory {
|
||||
|
||||
private void validateStreamSource(StreamSource streamSource,
|
||||
SAXParser parser,
|
||||
ValidationErrorHandler errorHandler) throws SAXException, IOException {
|
||||
DefaultValidationErrorHandler errorHandler) throws SAXException, IOException {
|
||||
if (streamSource.getInputStream() != null) {
|
||||
parser.parse(streamSource.getInputStream(), errorHandler);
|
||||
}
|
||||
@@ -135,7 +142,7 @@ abstract class Jaxp10ValidatorFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private void validateSAXSource(SAXSource source, SAXParser parser, ValidationErrorHandler errorHandler)
|
||||
private void validateSAXSource(SAXSource source, SAXParser parser, DefaultValidationErrorHandler errorHandler)
|
||||
throws SAXException, IOException {
|
||||
parser.parse(source.getInputSource(), errorHandler);
|
||||
}
|
||||
@@ -157,7 +164,7 @@ abstract class Jaxp10ValidatorFactory {
|
||||
}
|
||||
|
||||
/** <code>DefaultHandler</code> extension that stores errors and fatal errors in a list. */
|
||||
private static class ValidationErrorHandler extends DefaultHandler {
|
||||
private static class DefaultValidationErrorHandler extends DefaultHandler {
|
||||
|
||||
private List<SAXParseException> errors = new ArrayList<SAXParseException>();
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2005-2010 the original author or authors.
|
||||
* Copyright 2005-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -21,10 +21,10 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.Validator;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
@@ -55,8 +55,14 @@ abstract class Jaxp13ValidatorFactory {
|
||||
}
|
||||
|
||||
public SAXParseException[] validate(Source source) throws IOException {
|
||||
javax.xml.validation.Validator validator = schema.newValidator();
|
||||
ValidationErrorHandler errorHandler = new ValidationErrorHandler();
|
||||
return validate(source, null);
|
||||
}
|
||||
|
||||
public SAXParseException[] validate(Source source, ValidationErrorHandler errorHandler) throws IOException {
|
||||
if (errorHandler == null) {
|
||||
errorHandler = new DefaultValidationErrorHandler();
|
||||
}
|
||||
Validator validator = schema.newValidator();
|
||||
validator.setErrorHandler(errorHandler);
|
||||
try {
|
||||
validator.validate(source);
|
||||
@@ -69,11 +75,11 @@ abstract class Jaxp13ValidatorFactory {
|
||||
}
|
||||
|
||||
/** <code>ErrorHandler</code> implementation that stores errors and fatal errors in a list. */
|
||||
private static class ValidationErrorHandler implements ErrorHandler {
|
||||
private static class DefaultValidationErrorHandler implements ValidationErrorHandler {
|
||||
|
||||
private List<SAXParseException> errors = new ArrayList<SAXParseException>();
|
||||
|
||||
private SAXParseException[] getErrors() {
|
||||
public SAXParseException[] getErrors() {
|
||||
return errors.toArray(new SAXParseException[errors.size()]);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2005-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.xml.validation;
|
||||
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
/**
|
||||
* Subinterface of {@link ErrorHandler} that allows the registered errors to be retrieved.
|
||||
* @author Arjen Poutsma
|
||||
* @since 2.0.1
|
||||
*/
|
||||
public interface ValidationErrorHandler extends ErrorHandler {
|
||||
|
||||
/**
|
||||
* Returns the errors collected by this error handler.
|
||||
* @return the errors
|
||||
*/
|
||||
SAXParseException[] getErrors();
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
* Copyright 2005-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -27,7 +27,7 @@ import org.xml.sax.SAXParseException;
|
||||
* Instances of this class are designed to be thread safe.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see XmlValidatorFactory#createValidator(org.springframework.core.io.Resource,String)
|
||||
* @see XmlValidatorFactory#createValidator(org.springframework.core.io.Resource, String)
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public interface XmlValidator {
|
||||
@@ -43,4 +43,16 @@ public interface XmlValidator {
|
||||
*/
|
||||
SAXParseException[] validate(Source source) throws IOException;
|
||||
|
||||
/**
|
||||
* Validates the given {@link Source} and {@link ValidationErrorHandler}, and returns an array of {@link
|
||||
* SAXParseException}s as result. The array will be empty if no validation errors are found.
|
||||
*
|
||||
* @param source the input document
|
||||
* @param errorHandler the error handler to use. May be {@code null}, in which case a default will be used.
|
||||
* @return an array of <code>SAXParseException</code>s
|
||||
* @throws IOException if the <code>source</code> cannot be read
|
||||
* @throws XmlValidationException if the <code>source</code> cannot be validated
|
||||
*/
|
||||
SAXParseException[] validate(Source source, ValidationErrorHandler errorHandler) throws IOException;
|
||||
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2005-2010 the original author or authors.
|
||||
* Copyright 2005-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -91,12 +91,8 @@ public abstract class XmlValidatorFactory {
|
||||
logger.trace("Creating JAXP 1.3 XmlValidator");
|
||||
return Jaxp13ValidatorFactory.createValidator(schemaResources, schemaLanguage);
|
||||
}
|
||||
else if (JaxpVersion.getJaxpVersion() >= JaxpVersion.JAXP_10) {
|
||||
logger.trace("Creating JAXP 1.0 XmlValidator");
|
||||
return Jaxp10ValidatorFactory.createValidator(schemaResources, schemaLanguage);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Could not locate JAXP 1.0 or higher.");
|
||||
throw new IllegalStateException("Could not locate JAXP 1.3.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2005-2010 the original author or authors.
|
||||
* Copyright 2005-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -33,6 +33,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
public abstract class AbstractValidatorFactoryTestCase {
|
||||
@@ -135,4 +136,25 @@ public abstract class AbstractValidatorFactoryTestCase {
|
||||
Assert.assertEquals("ValidationErrors returned", 0, errors.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customErrorHandler() throws Exception {
|
||||
ValidationErrorHandler myHandler = new ValidationErrorHandler() {
|
||||
public SAXParseException[] getErrors() {
|
||||
return new SAXParseException[0];
|
||||
}
|
||||
|
||||
public void warning(SAXParseException exception) throws SAXException {
|
||||
}
|
||||
|
||||
public void error(SAXParseException exception) throws SAXException {
|
||||
}
|
||||
|
||||
public void fatalError(SAXParseException exception) throws SAXException {
|
||||
}
|
||||
};
|
||||
SAXParseException[] errors = validator.validate(new StreamSource(invalidInputStream), myHandler);
|
||||
Assert.assertNotNull("Null returned for errors", errors);
|
||||
Assert.assertEquals("ValidationErrors returned", 0, errors.length);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2005-2010 the original author or authors.
|
||||
* Copyright 2005-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -26,4 +26,9 @@ public class Jaxp10ValidatorFactoryTest extends AbstractValidatorFactoryTestCase
|
||||
protected XmlValidator createValidator(Resource[] schemaResources, String schemaLanguage) throws IOException {
|
||||
return Jaxp10ValidatorFactory.createValidator(schemaResources, schemaLanguage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customErrorHandler() throws Exception {
|
||||
// Not supported on JAXP 1.0
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user