Error Handling
Spring WS provides way by handling exceptions arising when the endpoint processes the received message by the way of EndpointExceptionResolver’s. These exception resolvers provide information about what endpoint was invoked when the exception was thrown. Listing 16-14 shows the ExceptionResolver interface which should be implemented for by your exception resolvers.
Listing 16-14. ExceptionResolver interface definition
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package org.springframework.ws.server; import org.springframework.ws.context. MessageContext; import java.util.Exception; public interface EndpointExceptionResolver{ boolean resolveException( MessageContext messageContext, Object endpoint, Exception ex); } |
The class org.springframework.ws.soap.server.endpoint.SimpleSoapExceptionResolver is the simplest implementation of ExceptionResolver interface and creates a SOAP 1.1 Server or SOAP 1.2 Receiver Fault, and uses the exception message as the fault string. The class org.springframework.ws.soap.server.endpoint.SoapFaultMappingExceptionResolver is a more sophisticated implementation. This resolver enables you to take the class name of any exception that might be thrown and map it to a SOAP Fault. Listing 16-15 shows configuring SoapFaultMappingExceptionResolver in Spring configuration.
Listing 16-15. Configuring SoapFaultMappingExceptionResolver in Spring configuration file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<bean id="soapFaultExceptionResolver" class="org.springframework.ws.soap.server.endpoint.SoapFaultMappingExceptionResolver"> <property name="defaultFault" value="SERVER"/> <property name="exceptionMappings"> <value> org.springframework.oxm.ValidationFailureException=CLIENT, Invalid request </value> </property> </bean> |
Securing Spring WS
Spring WS has built-in support for WS-Security. It supports all security features like authentication (is the caller authorized to use the service?), digital signing (caller is who he says?) and encryption/decryption (protect sensitive information). Implementing security is as simple as declaring appropriate interceptors in the Spring configuration file. There are two interceptors which need mention, they are as summarized below:
- org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor – it is based on Sun XML and Web Services Security package (XWSS) and requires JDK 1.4+.
- org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor – based on Apache WSS4J.
The various configuration steps in server side can be summarized as below:
- Add filters/interceptors to the EndpointMapping declared in earlier section.Listing 16-16 shows this declaration.
Listing 16-16. Declaring filters/interceptors in EndpointMapping
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<bean id=“payloadMapping” class=“org.springframework.ws.server.endpoint. mapping.PayloadRootAnnotationMethodEndpointMapping”> <property name="interceptors"> <list> <ref local="wsServerSecurityInterceptor" /> </list> </property> </bean> |
- Define the interceptor defined in the previous step in the Spring configuration file as shown in Listing 16-17 below. We are using Wss4jSecurityInterceptor in our configuration and to make it more complicated we will be using encryption with keystore, certificate and private key. I know its too complicated using this, but I thought this will be the case in new generation application requiring more secure web services.
Listing 16-17. Define the WS security interceptor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<bean id="wsServerSecurityInterceptor"> <property name="validationActions" value="Timestamp Signature Encrypt"/> <property name="validationSignatureCrypto" ref="serverCrypto"/> <property name="validationDecryptionCrypto" ref="serverCrypto"/> <property name="validationCallbackHandler"> <bean class="org.springframework.ws.soap.security.wss4j.callback.KeyStoreCallbackHandler"> <property name="keyStore"> <bean class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean"> <property name="password" value="passwd"/> </bean> </property> <property name="privateKeyPassword" value=""/> </bean> </property> <property name="securementActions" value="Signature" /> <property name="securementUsername" value="server" /> <property name="securementPassword" value="" /> <property name="securementSignatureCrypto" ref="serverCrypto"/> </bean> <bean id="serverCrypto" class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean"> <property name="keyStorePassword" value="passwd"/> <property name="keyStoreLocation" value="classpath:security/server-keystore.jks"/> </bean> |
The various configuration steps in client side can be summarized as below:
- In the WebserviceTemplate configuration add the interceptors as shown in Listing 16-18 below.
Listing 16-18. Adding interceptors to WebserviceTemplate bean configuration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<bean id="webserviceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate"> <property name="interceptors"> <list> <ref local="wsClientSecurityInterceptor"/> </list> </property> ... </bean> |
- Declare the interceptor configured in previous step as shown in Listing 16-19 below. Since we have declared encryption in the server side, we will incorporate the same encryption in the client-side as well.
Listing 16-19. Configuring interceptor in the client side in the Spring configuration file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<bean id="wsClientSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor"> <property name="securementActions" value="Timestamp Signature Encrypt" /> <property name="securementUsername" value="client" /> <property name="securementPassword" value="" /> <property name="securementSignatureCrypto" ref="clientCrypto"/> <property name="securementEncryptionCrypto" ref="clientCrypto"/> <property name="securementEncryptionParts" value="{Content}"/> <property name="securementEncryptionUser" value="server"/> <property name="validationActions" value="Signature" /> <property name="validationSignatureCrypto" ref="clientCrypto"/> </bean> <bean id="clientCrypto" class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean"> <property name="keyStorePassword" value="passwd"/> <property name="keyStoreLocation" value="classpath:security/client-keystore.jks"/> </bean> |
Without any Java code change and by mere change in the Spring configuration we achieved security in the already configured web service.
Page Visitors: 10889

Tomcy John

Latest posts by Tomcy John (see all)
- A Guide to Continuous Improvement for Architects - February 2, 2023
- Cloud-first Architecture Strategy - January 26, 2023
- Architecture Strategy and how to create One - January 24, 2023