This commit is contained in:
Arjen Poutsma
2007-10-29 12:42:30 +00:00
parent 39de154e18
commit 85c94b0c01
5 changed files with 52 additions and 334 deletions

View File

@@ -24,6 +24,7 @@ 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;
@@ -50,6 +51,8 @@ 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.
@@ -119,6 +122,30 @@ 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");

View File

@@ -66,7 +66,8 @@ public abstract class AbstractSoapFaultDefinitionExceptionResolver extends Abstr
return false;
}
if (!StringUtils.hasLength(definition.getFaultStringOrReason())) {
definition.setFaultStringOrReason(ex.getMessage());
String faultString = StringUtils.hasLength(ex.getMessage()) ? ex.getMessage() : ex.toString();
definition.setFaultStringOrReason(faultString);
}
SoapBody soapBody = ((SoapMessage) messageContext.getResponse()).getSoapBody();
SoapFault fault = null;

View File

@@ -16,6 +16,7 @@
package org.springframework.ws.soap.server.endpoint;
import java.io.IOException;
import java.util.Locale;
import java.util.Properties;
import javax.xml.soap.MessageFactory;
@@ -167,5 +168,27 @@ public class SoapFaultMappingExceptionResolverTest extends XMLTestCase {
assertNull("Detail on fault", fault.getFaultDetail());
}
public void testResolveNoMessageException() throws Exception {
Properties mappings = new Properties();
mappings.setProperty(IOException.class.getName(), "SERVER");
resolver.setExceptionMappings(mappings);
MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
SOAPMessage message = messageFactory.createMessage();
SoapMessageFactory factory = new SaajSoapMessageFactory(messageFactory);
MessageContext context = new DefaultMessageContext(new SaajSoapMessage(message), factory);
boolean result = resolver.resolveException(context, null, new IOException());
assertTrue("resolveException returns false", result);
assertTrue("Context has no response", context.hasResponse());
SoapMessage response = (SoapMessage) context.getResponse();
assertTrue("Response has no fault", response.getSoapBody().hasFault());
Soap11Fault fault = (Soap11Fault) response.getSoapBody().getFault();
assertEquals("Invalid fault code on fault", SoapVersion.SOAP_11.getServerOrReceiverFaultName(),
fault.getFaultCode());
assertEquals("Invalid fault string on fault", "java.io.IOException", fault.getFaultStringOrReason());
assertNull("Detail on fault", fault.getFaultDetail());
}
}

View File

@@ -1,207 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:schema="http://www.springframework.org/spring-ws/samples/airline/schemas"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.springframework.org/spring-ws/wsdl/definitions"
targetNamespace="http://www.springframework.org/spring-ws/wsdl/definitions">
<wsdl:types>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://www.springframework.org/spring-ws/samples/airline/schemas"
elementFormDefault="qualified"
targetNamespace="http://www.springframework.org/spring-ws/samples/airline/schemas">
<element name="GetFlightsRequest">
<complexType>
<all>
<element name="from" type="tns:AirportCode"/>
<element name="to" type="tns:AirportCode"/>
<element name="departureDate" type="date"/>
<element minOccurs="0" name="serviceClass" type="tns:ServiceClass"/>
</all>
</complexType>
</element>
<element name="GetFlightsResponse">
<complexType>
<sequence>
<element maxOccurs="unbounded" minOccurs="0" name="flight" type="tns:Flight"/>
</sequence>
</complexType>
</element>
<element name="GetFlightsFault">
<complexType>
<sequence>
<element name="errorCode" type="string"/>
</sequence>
</complexType>
</element>
<element name="BookFlightRequest">
<complexType>
<all>
<element name="flightNumber" type="tns:FlightNumber"/>
<element name="departureTime" type="dateTime"/>
<element name="passengers">
<complexType>
<choice maxOccurs="9">
<element name="passenger" type="tns:Name"/>
<element name="username" type="tns:FrequentFlyerUsername"/>
</choice>
</complexType>
</element>
</all>
</complexType>
</element>
<element name="BookFlightResponse" type="tns:Ticket"/>
<element name="GetFrequentFlyerMileageRequest"/>
<element name="GetFrequentFlyerMileageResponse" type="int"/>
<complexType name="Flight">
<sequence>
<element name="number" type="tns:FlightNumber"/>
<element name="departureTime" type="dateTime"/>
<element name="from" type="tns:Airport"/>
<element name="arrivalTime" type="dateTime"/>
<element name="to" type="tns:Airport"/>
<element name="serviceClass" type="tns:ServiceClass"/>
</sequence>
</complexType>
<simpleType name="FlightNumber">
<restriction base="string">
<pattern value="[A-Z][A-Z][0-9][0-9][0-9][0-9]"/>
</restriction>
</simpleType>
<complexType name="Name">
<sequence>
<element name="first" type="string"/>
<element name="last" type="string"/>
</sequence>
</complexType>
<simpleType name="FrequentFlyerUsername">
<restriction base="string"/>
</simpleType>
<complexType name="Airport">
<all>
<element name="code" type="tns:AirportCode"/>
<element name="name" type="string"/>
<element name="city" type="string"/>
</all>
</complexType>
<simpleType name="AirportCode">
<restriction base="string">
<pattern value="[A-Z][A-Z][A-Z]"/>
</restriction>
</simpleType>
<complexType name="Ticket">
<all>
<element name="id" type="long"/>
<element name="issueDate" type="date"/>
<element name="passengers">
<complexType>
<sequence>
<element maxOccurs="9" name="passenger" type="tns:Name"/>
</sequence>
</complexType>
</element>
<element name="flight" type="tns:Flight"/>
</all>
</complexType>
<simpleType name="ServiceClass">
<restriction base="NCName">
<enumeration value="economy"/>
<enumeration value="business"/>
<enumeration value="first"/>
</restriction>
</simpleType>
</schema>
</wsdl:types>
<wsdl:message name="GetFrequentFlyerMileageResponse">
<wsdl:part element="schema:GetFrequentFlyerMileageResponse" name="GetFrequentFlyerMileageResponse"/>
</wsdl:message>
<wsdl:message name="BookFlightResponse">
<wsdl:part element="schema:BookFlightResponse" name="BookFlightResponse"/>
</wsdl:message>
<wsdl:message name="GetFlightsRequest">
<wsdl:part element="schema:GetFlightsRequest" name="GetFlightsRequest"/>
</wsdl:message>
<wsdl:message name="GetFlightsFault">
<wsdl:part element="schema:GetFlightsFault" name="GetFlightsFault"/>
</wsdl:message>
<wsdl:message name="GetFrequentFlyerMileageRequest">
<wsdl:part element="schema:GetFrequentFlyerMileageRequest" name="GetFrequentFlyerMileageRequest"/>
</wsdl:message>
<wsdl:message name="GetFlightsResponse">
<wsdl:part element="schema:GetFlightsResponse" name="GetFlightsResponse"/>
</wsdl:message>
<wsdl:message name="BookFlightRequest">
<wsdl:part element="schema:BookFlightRequest" name="BookFlightRequest"/>
</wsdl:message>
<wsdl:portType name="Airline">
<wsdl:operation name="GetFlights">
<wsdl:input message="tns:GetFlightsRequest" name="GetFlightsRequest"/>
<wsdl:output message="tns:GetFlightsResponse" name="GetFlightsResponse"/>
<wsdl:fault message="tns:GetFlightsFault" name="GetFlightsFault"/>
</wsdl:operation>
<wsdl:operation name="GetFrequentFlyerMileage">
<wsdl:input message="tns:GetFrequentFlyerMileageRequest" name="GetFrequentFlyerMileageRequest"/>
<wsdl:output message="tns:GetFrequentFlyerMileageResponse" name="GetFrequentFlyerMileageResponse"/>
</wsdl:operation>
<wsdl:operation name="BookFlight">
<wsdl:input message="tns:BookFlightRequest" name="BookFlightRequest"/>
<wsdl:output message="tns:BookFlightResponse" name="BookFlightResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="AirlineBinding" type="tns:Airline">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GetFlights">
<soap:operation soapAction=""/>
<wsdl:input name="GetFlightsRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="GetFlightsResponse">
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="GetFlightsFault">
<soap:fault name="GetFlightsFault" use="literal"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="GetFrequentFlyerMileage">
<soap:operation soapAction=""/>
<wsdl:input name="GetFrequentFlyerMileageRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="GetFrequentFlyerMileageResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="BookFlight">
<soap:operation soapAction=""/>
<wsdl:input name="BookFlightRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="BookFlightResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="AirlineService">
<wsdl:port binding="tns:AirlineBinding" name="AirlinePort">
<soap:address location="http://localhost:8080/"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

View File

@@ -1,126 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.springframework.org/spring-ws/samples/airline/schemas"
xmlns:tns="http://www.springframework.org/spring-ws/samples/airline/schemas"
elementFormDefault="qualified">
<element name="GetFlightsRequest">
<complexType>
<all>
<element name="from" type="tns:AirportCode"/>
<element name="to" type="tns:AirportCode"/>
<element name="departureDate" type="date"/>
<element name="serviceClass" type="tns:ServiceClass" minOccurs="0"/>
</all>
</complexType>
</element>
<element name="GetFlightsResponse">
<complexType>
<sequence>
<element name="flight" type="tns:Flight" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>
<element name="GetFlightsFault">
<complexType>
<sequence>
<element name="errorCode" type="string"/>
</sequence>
</complexType>
</element>
<element name="BookFlightRequest">
<complexType>
<all>
<element name="flightNumber" type="tns:FlightNumber"/>
<element name="departureTime" type="dateTime"/>
<element name="passengers">
<complexType>
<choice maxOccurs="9">
<element name="passenger" type="tns:Name"/>
<element name="username" type="tns:FrequentFlyerUsername"/>
</choice>
</complexType>
</element>
</all>
</complexType>
</element>
<element name="BookFlightResponse" type="tns:Ticket"/>
<element name="GetFrequentFlyerMileageRequest"/>
<element name="GetFrequentFlyerMileageResponse" type="int"/>
<complexType name="Flight">
<sequence>
<element name="number" type="tns:FlightNumber"/>
<element name="departureTime" type="dateTime"/>
<element name="from" type="tns:Airport"/>
<element name="arrivalTime" type="dateTime"/>
<element name="to" type="tns:Airport"/>
<element name="serviceClass" type="tns:ServiceClass"/>
</sequence>
</complexType>
<simpleType name="FlightNumber">
<restriction base="string">
<pattern value="[A-Z][A-Z][0-9][0-9][0-9][0-9]"/>
</restriction>
</simpleType>
<complexType name="Name">
<sequence>
<element name="first" type="string"/>
<element name="last" type="string"/>
</sequence>
</complexType>
<simpleType name="FrequentFlyerUsername">
<restriction base="string"/>
</simpleType>
<complexType name="Airport">
<all>
<element name="code" type="tns:AirportCode"/>
<element name="name" type="string"/>
<element name="city" type="string"/>
</all>
</complexType>
<simpleType name="AirportCode">
<restriction base="string">
<pattern value="[A-Z][A-Z][A-Z]"/>
</restriction>
</simpleType>
<complexType name="Ticket">
<all>
<element name="id" type="long"/>
<element name="issueDate" type="date"/>
<element name="passengers">
<complexType>
<sequence>
<element name="passenger" type="tns:Name" maxOccurs="9"/>
</sequence>
</complexType>
</element>
<element name="flight" type="tns:Flight"/>
</all>
</complexType>
<simpleType name="ServiceClass">
<restriction base="NCName">
<enumeration value="economy"/>
<enumeration value="business"/>
<enumeration value="first"/>
</restriction>
</simpleType>
</schema>