SWS-81
This commit is contained in:
@@ -24,7 +24,6 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.oxm.Marshaller;
|
||||
import org.springframework.oxm.Unmarshaller;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.support.MarshallingUtils;
|
||||
@@ -51,8 +50,6 @@ public abstract class AbstractMarshallingPayloadEndpoint implements MessageEndpo
|
||||
|
||||
private Unmarshaller unmarshaller;
|
||||
|
||||
private Validator[] validators;
|
||||
|
||||
/**
|
||||
* Creates a new <code>AbstractMarshallingPayloadEndpoint</code>. The {@link Marshaller} and {@link Unmarshaller}
|
||||
* must be injected using properties.
|
||||
@@ -122,30 +119,6 @@ public abstract class AbstractMarshallingPayloadEndpoint implements MessageEndpo
|
||||
this.unmarshaller = unmarshaller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the primary {@link Validator} for this endpoint. The {@link Validator} is must support the specified command
|
||||
* class. If there are one or more existing validators set already when this method is called, only the specified
|
||||
* validator will be kept. Use {@link #setValidators(Validator[])} to set multiple validators.
|
||||
*/
|
||||
public final void setValidator(Validator validator) {
|
||||
this.validators = new Validator[]{validator};
|
||||
}
|
||||
|
||||
/** Return the primary Validator for this controller. */
|
||||
public final Validator getValidator() {
|
||||
return (this.validators != null && this.validators.length > 0 ? this.validators[0] : null);
|
||||
}
|
||||
|
||||
/** Set the Validators for this controller. The Validator must support the specified command class. */
|
||||
public final void setValidators(Validator[] validators) {
|
||||
this.validators = validators;
|
||||
}
|
||||
|
||||
/** Return the Validators for this controller. */
|
||||
public final Validator[] getValidators() {
|
||||
return validators;
|
||||
}
|
||||
|
||||
public final void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(getMarshaller(), "marshaller is required");
|
||||
Assert.notNull(getUnmarshaller(), "unmarshaller is required");
|
||||
@@ -155,10 +128,13 @@ public abstract class AbstractMarshallingPayloadEndpoint implements MessageEndpo
|
||||
public final void invoke(MessageContext messageContext) throws Exception {
|
||||
WebServiceMessage request = messageContext.getRequest();
|
||||
Object requestObject = unmarshalRequest(request);
|
||||
Object responseObject = invokeInternal(requestObject);
|
||||
if (responseObject != null) {
|
||||
WebServiceMessage response = messageContext.getResponse();
|
||||
marshalResponse(responseObject, response);
|
||||
if (onUnmarshalRequest(messageContext, requestObject)) {
|
||||
Object responseObject = invokeInternal(requestObject);
|
||||
if (responseObject != null) {
|
||||
WebServiceMessage response = messageContext.getResponse();
|
||||
marshalResponse(responseObject, response);
|
||||
onMarshalResponse(messageContext, requestObject, responseObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,6 +146,20 @@ public abstract class AbstractMarshallingPayloadEndpoint implements MessageEndpo
|
||||
return requestObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for post-processing in terms of unmarshalling. Called on each message request, after standard
|
||||
* unmarshalling.
|
||||
* <p/>
|
||||
* Default implementation returns <code>true</code>.
|
||||
*
|
||||
* @param messageContext the message context
|
||||
* @param requestObject the object unmarshalled from the {@link MessageContext#getRequest() request}
|
||||
* @return <code>true</code> to continue and call {@link #invokeInternal(Object)}; <code>false</code> otherwise
|
||||
*/
|
||||
protected boolean onUnmarshalRequest(MessageContext messageContext, Object requestObject) throws Exception {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void marshalResponse(Object responseObject, WebServiceMessage response) throws IOException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Marshalling [" + responseObject + "] to response payload");
|
||||
@@ -177,6 +167,19 @@ public abstract class AbstractMarshallingPayloadEndpoint implements MessageEndpo
|
||||
MarshallingUtils.marshal(getMarshaller(), responseObject, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for post-processing in terms of marshalling. Called on each message request, after standard marshalling
|
||||
* of the response. Only invoked when {@link #invokeInternal(Object)} returns an object.
|
||||
* <p/>
|
||||
* Default implementation is empty.
|
||||
*
|
||||
* @param messageContext the message context
|
||||
* @param requestObject the object unmarshalled from the {@link MessageContext#getRequest() request}
|
||||
* @param responseObject the object marshalled to the {@link MessageContext#getResponse()} request}
|
||||
*/
|
||||
protected void onMarshalResponse(MessageContext messageContext, Object requestObject, Object responseObject) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Template method that gets called after the marshaller and unmarshaller have been set.
|
||||
* <p/>
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2007 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.ws.server.endpoint;
|
||||
|
||||
import org.springframework.validation.BeanPropertyBindingResult;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.ValidationUtils;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
|
||||
/**
|
||||
* Extension of the {@link AbstractMarshallingPayloadEndpoint} which validates the request payload with {@link
|
||||
* Validator}(s). The desired validators can be set using properties, and <strong>must</strong> {@link
|
||||
* Validator#supports(Class) support} the request object.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.0.2
|
||||
*/
|
||||
public abstract class AbstractValidatingMarshallingPayloadEndpoint extends AbstractMarshallingPayloadEndpoint {
|
||||
|
||||
/** Default request object name used for validating request objects. */
|
||||
public static final String DEFAULT_REQUEST_NAME = "request";
|
||||
|
||||
private String requestName = DEFAULT_REQUEST_NAME;
|
||||
|
||||
private Validator[] validators;
|
||||
|
||||
/** Return the name of the request object for validation error codes. */
|
||||
public final String getRequestName() {
|
||||
return requestName;
|
||||
}
|
||||
|
||||
/** Set the name of the request object user for validation errors. */
|
||||
public final void setRequestName(String requestName) {
|
||||
this.requestName = requestName;
|
||||
}
|
||||
|
||||
/** Return the primary Validator for this controller. */
|
||||
public final Validator getValidator() {
|
||||
return (this.validators != null && this.validators.length > 0 ? this.validators[0] : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the primary {@link Validator} for this endpoint. The {@link Validator} is must support the unmarshalled
|
||||
* class. If there are one or more existing validators set already when this method is called, only the specified
|
||||
* validator will be kept. Use {@link #setValidators(Validator[])} to set multiple validators.
|
||||
*/
|
||||
public final void setValidator(Validator validator) {
|
||||
this.validators = new Validator[]{validator};
|
||||
}
|
||||
|
||||
/** Return the Validators for this controller. */
|
||||
public final Validator[] getValidators() {
|
||||
return validators;
|
||||
}
|
||||
|
||||
/** Set the Validators for this controller. The Validator must support the specified command class. */
|
||||
public final void setValidators(Validator[] validators) {
|
||||
this.validators = validators;
|
||||
}
|
||||
|
||||
protected final boolean onUnmarshalRequest(MessageContext messageContext, Object requestObject) throws Exception {
|
||||
if (validators != null) {
|
||||
Errors errors = new BeanPropertyBindingResult(requestObject, getRequestName());
|
||||
for (int i = 0; i < validators.length; i++) {
|
||||
ValidationUtils.invokeValidator(validators[i], requestObject, errors);
|
||||
}
|
||||
if (errors.hasErrors()) {
|
||||
return onValidationErrors(messageContext, requestObject, errors);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for post-processing validation errors. Called when validator(s) have been specified, and validation
|
||||
* fails.
|
||||
*
|
||||
* @param messageContext the message context
|
||||
* @param requestObject the object unmarshalled from the {@link MessageContext#getRequest() request}
|
||||
* @param errors validation errors holder
|
||||
* @return <code>true</code> to continue and call {@link #invokeInternal(Object)}; <code>false</code> otherwise
|
||||
*/
|
||||
protected abstract boolean onValidationErrors(MessageContext messageContext, Object requestObject, Errors errors);
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright 2007 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.ws.soap.server.endpoint;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.MessageSourceAware;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.ObjectError;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.server.endpoint.AbstractValidatingMarshallingPayloadEndpoint;
|
||||
import org.springframework.ws.soap.SoapBody;
|
||||
import org.springframework.ws.soap.SoapFault;
|
||||
import org.springframework.ws.soap.SoapFaultDetail;
|
||||
import org.springframework.ws.soap.SoapFaultDetailElement;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.xml.namespace.QNameUtils;
|
||||
|
||||
/**
|
||||
* Extension of the {@link AbstractValidatingMarshallingPayloadEndpoint} which validates the request payload with {@link
|
||||
* Validator}(s), and creates a SOAP Fault whenever the request message cannot be validated. The desired validators can
|
||||
* be set using properties, and <strong>must</strong> {@link Validator#supports(Class) support} the request object.
|
||||
* <p/>
|
||||
* The contents of the SOAP Fault can be specified by setting the {@link #setAddValidationErrorDetail(boolean)
|
||||
* addValidationErrorDetail}, {@link #setFaultStringOrReason(String) faultStringOrReason}, or {@link
|
||||
* #setDetailElementName(QName) detailElementName} properties.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.0.2
|
||||
*/
|
||||
public abstract class AbstractFaultCreatingValidatingMarshallingPayloadEndpoint
|
||||
extends AbstractValidatingMarshallingPayloadEndpoint implements MessageSourceAware {
|
||||
|
||||
/**
|
||||
* Default SOAP Fault Detail name used when a global validation error occur on the request.
|
||||
*
|
||||
* @see #setDetailElementName(javax.xml.namespace.QName)
|
||||
*/
|
||||
public static final QName DEFAULT_DETAIL_ELEMENT_NAME =
|
||||
QNameUtils.createQName("http://springframework.org/spring-ws", "ValidationError", "spring-ws");
|
||||
|
||||
/**
|
||||
* Default SOAP Fault string used when a validation errors occur on the request.
|
||||
*
|
||||
* @see #setFaultStringOrReason(String)
|
||||
*/
|
||||
public static final String DEFAULT_FAULTSTRING_OR_REASON = "Validation error";
|
||||
|
||||
private boolean addValidationErrorDetail = true;
|
||||
|
||||
private QName detailElementName = DEFAULT_DETAIL_ELEMENT_NAME;
|
||||
|
||||
private String faultStringOrReason = DEFAULT_FAULTSTRING_OR_REASON;
|
||||
|
||||
private Locale faultStringOrReasonLocale = Locale.ENGLISH;
|
||||
|
||||
private MessageSource messageSource;
|
||||
|
||||
/**
|
||||
* Returns whether a SOAP Fault detail element should be created when a validation error occurs. This detail element
|
||||
* will contain the exact validation errors. It is only added when the underlying message is a
|
||||
* <code>SoapMessage</code>. Defaults to <code>true</code>.
|
||||
*
|
||||
* @see org.springframework.ws.soap.SoapFault#addFaultDetail()
|
||||
*/
|
||||
public boolean getAddValidationErrorDetail() {
|
||||
return addValidationErrorDetail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether a SOAP Fault detail element should be created when a validation error occurs. This detail
|
||||
* element will contain the exact validation errors. It is only added when the underlying message is a
|
||||
* <code>SoapMessage</code>. Defaults to <code>true</code>.
|
||||
*
|
||||
* @see org.springframework.ws.soap.SoapFault#addFaultDetail()
|
||||
*/
|
||||
public void setAddValidationErrorDetail(boolean addValidationErrorDetail) {
|
||||
this.addValidationErrorDetail = addValidationErrorDetail;
|
||||
}
|
||||
|
||||
/** Returns the fault detail element name when validation errors occur on the request. */
|
||||
public QName getDetailElementName() {
|
||||
return detailElementName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the fault detail element name when validation errors occur on the request. Defaults to
|
||||
* <code>DEFAULT_DETAIL_ELEMENT_NAME</code>.
|
||||
*
|
||||
* @see #DEFAULT_DETAIL_ELEMENT_NAME
|
||||
*/
|
||||
public void setDetailElementName(QName detailElementName) {
|
||||
this.detailElementName = detailElementName;
|
||||
}
|
||||
|
||||
/** Sets the SOAP <code>faultstring</code> or <code>Reason</code> used when validation errors occur on the request. */
|
||||
public String getFaultStringOrReason() {
|
||||
return faultStringOrReason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the SOAP <code>faultstring</code> or <code>Reason</code> used when validation errors occur on the request.
|
||||
* It is only added when the underlying message is a <code>SoapMessage</code>. Defaults to
|
||||
* <code>DEFAULT_FAULTSTRING_OR_REASON</code>.
|
||||
*
|
||||
* @see #DEFAULT_FAULTSTRING_OR_REASON
|
||||
*/
|
||||
public void setFaultStringOrReason(String faultStringOrReason) {
|
||||
this.faultStringOrReason = faultStringOrReason;
|
||||
}
|
||||
|
||||
/** Returns the locale for SOAP fault reason and validation message resolution. */
|
||||
public Locale getFaultLocale() {
|
||||
return faultStringOrReasonLocale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the locale for SOAP fault reason and validation messages. It is only added when the underlying message is a
|
||||
* <code>SoapMessage</code>. Defaults to English.
|
||||
*
|
||||
* @see java.util.Locale#ENGLISH
|
||||
*/
|
||||
public void setFaultStringOrReasonLocale(Locale faultStringOrReasonLocale) {
|
||||
this.faultStringOrReasonLocale = faultStringOrReasonLocale;
|
||||
}
|
||||
|
||||
public final void setMessageSource(MessageSource messageSource) {
|
||||
this.messageSource = messageSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation logs all errors, returns <code>false</code>, and creates a {@link
|
||||
* SoapBody#addClientOrSenderFault(String,Locale) client or sender} {@link SoapFault}, adding a {@link
|
||||
* SoapFaultDetail} with all errors if the <code>addValidationErrorDetail</code> property is <code>true</code>.
|
||||
*
|
||||
* @param messageContext the message context
|
||||
* @param errors the validation errors
|
||||
* @return <code>true</code> to continue processing the request, <code>false</code> (the default) otherwise
|
||||
* @see Errors#getAllErrors()
|
||||
*/
|
||||
protected final boolean onValidationErrors(MessageContext messageContext, Object requestObject, Errors errors) {
|
||||
for (Iterator iterator = errors.getAllErrors().iterator(); iterator.hasNext();) {
|
||||
ObjectError objectError = (ObjectError) iterator.next();
|
||||
String msg = messageSource.getMessage(objectError, getFaultLocale());
|
||||
logger.warn("Validation error on request object[" + requestObject + "]: " + msg);
|
||||
}
|
||||
if (messageContext.getResponse() instanceof SoapMessage) {
|
||||
SoapMessage response = (SoapMessage) messageContext.getResponse();
|
||||
SoapBody body = response.getSoapBody();
|
||||
SoapFault fault = body.addClientOrSenderFault(getFaultStringOrReason(), getFaultLocale());
|
||||
if (getAddValidationErrorDetail()) {
|
||||
SoapFaultDetail detail = fault.addFaultDetail();
|
||||
for (Iterator iterator = errors.getAllErrors().iterator(); iterator.hasNext();) {
|
||||
ObjectError objectError = (ObjectError) iterator.next();
|
||||
String msg = messageSource.getMessage(objectError, getFaultLocale());
|
||||
SoapFaultDetailElement detailElement = detail.addFaultDetailElement(getDetailElementName());
|
||||
detailElement.addText(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright ${YEAR} 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.ws.soap.server.endpoint;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.soap.Detail;
|
||||
import javax.xml.soap.DetailEntry;
|
||||
import javax.xml.soap.MessageFactory;
|
||||
import javax.xml.soap.SOAPFault;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
import javax.xml.transform.Result;
|
||||
import javax.xml.transform.Source;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.springframework.context.support.ResourceBundleMessageSource;
|
||||
import org.springframework.oxm.Marshaller;
|
||||
import org.springframework.oxm.Unmarshaller;
|
||||
import org.springframework.oxm.XmlMappingException;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.ValidationUtils;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.ws.context.DefaultMessageContext;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.soap.saaj.SaajSoapMessage;
|
||||
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
|
||||
|
||||
public class FaultCreatingValidatingMarshallingPayloadEndpointTest extends TestCase {
|
||||
|
||||
private MessageContext messageContext;
|
||||
|
||||
private ResourceBundleMessageSource messageSource;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
this.messageSource = new ResourceBundleMessageSource();
|
||||
this.messageSource.setBasename("org.springframework.ws.soap.server.endpoint.messages");
|
||||
MessageFactory messageFactory = MessageFactory.newInstance();
|
||||
SOAPMessage request = messageFactory.createMessage();
|
||||
request.getSOAPBody().addBodyElement(new QName("http://www.springframework.org/spring-ws", "request"));
|
||||
messageContext =
|
||||
new DefaultMessageContext(new SaajSoapMessage(request), new SaajSoapMessageFactory(messageFactory));
|
||||
}
|
||||
|
||||
public void testValidationIncorrect() throws Exception {
|
||||
Person p = new Person("", -1);
|
||||
PersonMarshaller marshaller = new PersonMarshaller(p);
|
||||
|
||||
AbstractFaultCreatingValidatingMarshallingPayloadEndpoint endpoint =
|
||||
new AbstractFaultCreatingValidatingMarshallingPayloadEndpoint() {
|
||||
|
||||
protected Object invokeInternal(Object requestObject) throws Exception {
|
||||
fail("No expected");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
endpoint.setValidator(new PersonValidator());
|
||||
endpoint.setMessageSource(messageSource);
|
||||
endpoint.setMarshaller(marshaller);
|
||||
endpoint.setUnmarshaller(marshaller);
|
||||
|
||||
endpoint.invoke(messageContext);
|
||||
|
||||
SOAPMessage response = ((SaajSoapMessage) messageContext.getResponse()).getSaajMessage();
|
||||
assertTrue("Response has no fault", response.getSOAPBody().hasFault());
|
||||
SOAPFault fault = response.getSOAPBody().getFault();
|
||||
assertEquals("Invalid fault code", new QName("http://schemas.xmlsoap.org/soap/envelope/", "Client"),
|
||||
fault.getFaultCodeAsQName());
|
||||
assertEquals("Invalid fault string", endpoint.getFaultStringOrReason(), fault.getFaultString());
|
||||
Detail detail = fault.getDetail();
|
||||
assertNotNull("No detail", detail);
|
||||
Iterator iterator = detail.getDetailEntries();
|
||||
assertTrue("No detail entry", iterator.hasNext());
|
||||
DetailEntry detailEntry = (DetailEntry) iterator.next();
|
||||
assertEquals("Invalid detail entry name", new QName("http://springframework.org/spring-ws", "ValidationError"),
|
||||
detailEntry.getElementQName());
|
||||
assertEquals("Invalid detail entry text", "Name is required", detailEntry.getTextContent());
|
||||
assertTrue("No detail entry", iterator.hasNext());
|
||||
detailEntry = (DetailEntry) iterator.next();
|
||||
assertEquals("Invalid detail entry name", new QName("http://springframework.org/spring-ws", "ValidationError"),
|
||||
detailEntry.getElementQName());
|
||||
assertEquals("Invalid detail entry text", "Age Cannot be negative", detailEntry.getTextContent());
|
||||
assertFalse("Too many detail entries", iterator.hasNext());
|
||||
}
|
||||
|
||||
public void testValidationCorrect() throws Exception {
|
||||
Person p = new Person("John", 42);
|
||||
PersonMarshaller marshaller = new PersonMarshaller(p);
|
||||
AbstractFaultCreatingValidatingMarshallingPayloadEndpoint endpoint =
|
||||
new AbstractFaultCreatingValidatingMarshallingPayloadEndpoint() {
|
||||
|
||||
protected Object invokeInternal(Object requestObject) throws Exception {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
endpoint.setValidator(new PersonValidator());
|
||||
endpoint.setMessageSource(messageSource);
|
||||
endpoint.setMarshaller(marshaller);
|
||||
endpoint.setUnmarshaller(marshaller);
|
||||
|
||||
endpoint.invoke(messageContext);
|
||||
|
||||
SOAPMessage response = ((SaajSoapMessage) messageContext.getResponse()).getSaajMessage();
|
||||
assertFalse("Response has fault", response.getSOAPBody().hasFault());
|
||||
}
|
||||
|
||||
private static class PersonValidator implements Validator {
|
||||
|
||||
public boolean supports(Class clazz) {
|
||||
return Person.class.equals(clazz);
|
||||
}
|
||||
|
||||
public void validate(Object obj, Errors e) {
|
||||
ValidationUtils.rejectIfEmpty(e, "name", "name.empty");
|
||||
Person p = (Person) obj;
|
||||
if (p.getAge() < 0) {
|
||||
e.rejectValue("age", "age.negativevalue");
|
||||
}
|
||||
else if (p.getAge() > 110) {
|
||||
e.rejectValue("age", "too.darn.old");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class Person {
|
||||
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
private Person(String name, int age) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Person{" + name + "," + age + "}";
|
||||
}
|
||||
}
|
||||
|
||||
private static class PersonMarshaller implements Unmarshaller, Marshaller {
|
||||
|
||||
private final Person person;
|
||||
|
||||
private PersonMarshaller(Person person) {
|
||||
this.person = person;
|
||||
}
|
||||
|
||||
public Object unmarshal(Source source) throws XmlMappingException, IOException {
|
||||
return person;
|
||||
}
|
||||
|
||||
public boolean supports(Class clazz) {
|
||||
return Person.class.equals(clazz);
|
||||
}
|
||||
|
||||
public void marshal(Object graph, Result result) throws XmlMappingException, IOException {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
name.empty=Name is required
|
||||
age.negativevalue=Age Cannot be negative
|
||||
Reference in New Issue
Block a user