/* * Copyright 2005-2014 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.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.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; /** * Extension of the {@link org.springframework.ws.server.endpoint.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 * @deprecated as of Spring Web Services 2.0, in favor of annotated endpoints */ @Deprecated public abstract class AbstractFaultCreatingValidatingMarshallingPayloadEndpoint extends org.springframework.ws.server.endpoint.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 = new QName("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}. Defaults to {@code true}. * * @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}. Defaults to {@code true}. * * @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}. * * @see #DEFAULT_DETAIL_ELEMENT_NAME */ public void setDetailElementName(QName detailElementName) { this.detailElementName = detailElementName; } /** Sets the SOAP {@code faultstring} or {@code Reason} used when validation errors occur on the request. */ public String getFaultStringOrReason() { return faultStringOrReason; } /** * Sets the SOAP {@code faultstring} or {@code Reason} used when validation errors occur on the request. * It is only added when the underlying message is a {@code SoapMessage}. Defaults to * {@code DEFAULT_FAULTSTRING_OR_REASON}. * * @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}. Defaults to English. * * @see java.util.Locale#ENGLISH */ public void setFaultStringOrReasonLocale(Locale faultStringOrReasonLocale) { this.faultStringOrReasonLocale = faultStringOrReasonLocale; } @Override public final void setMessageSource(MessageSource messageSource) { this.messageSource = messageSource; } /** * This implementation logs all errors, returns {@code false}, and creates a {@link * SoapBody#addClientOrSenderFault(String,Locale) client or sender} {@link SoapFault}, adding a {@link * SoapFaultDetail} with all errors if the {@code addValidationErrorDetail} property is {@code true}. * * @param messageContext the message context * @param errors the validation errors * @return {@code true} to continue processing the request, {@code false} (the default) otherwise * @see Errors#getAllErrors() */ @Override protected final boolean onValidationErrors(MessageContext messageContext, Object requestObject, Errors errors) { for (ObjectError objectError : errors.getAllErrors()) { 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 (ObjectError objectError : errors.getAllErrors()) { String msg = messageSource.getMessage(objectError, getFaultLocale()); SoapFaultDetailElement detailElement = detail.addFaultDetailElement(getDetailElementName()); detailElement.addText(msg); } } } return false; } }