Added afterCompletion to ClientInterceptor

Added the afterCompletion hook to ClientInterceptor, similar to the
existing one in EndpointInterceptor.

Issue: SWS-778
This commit is contained in:
Arjen Poutsma
2014-03-18 15:47:28 +01:00
parent a300d7ce1e
commit ac030c2ff3
5 changed files with 72 additions and 4 deletions

View File

@@ -568,12 +568,12 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
WebServiceConnection connection,
WebServiceMessageCallback requestCallback,
WebServiceMessageExtractor<T> responseExtractor) throws IOException {
int interceptorIndex = -1;
try {
if (requestCallback != null) {
requestCallback.doWithMessage(messageContext.getRequest());
}
// Apply handleRequest of registered interceptors
int interceptorIndex = -1;
if (interceptors != null) {
for (int i = 0; i < interceptors.length; i++) {
interceptorIndex = i;
@@ -586,7 +586,8 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
if (!messageContext.hasResponse()) {
sendRequest(connection, messageContext.getRequest());
if (hasError(connection, messageContext.getRequest())) {
return (T)handleError(connection, messageContext.getRequest());
triggerAfterCompletion(interceptorIndex, messageContext, null);
return (T) handleError(connection, messageContext.getRequest());
}
WebServiceMessage response = connection.receive(getMessageFactory());
messageContext.setResponse(response);
@@ -595,10 +596,12 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
if (messageContext.hasResponse()) {
if (!hasFault(connection, messageContext.getResponse())) {
triggerHandleResponse(interceptorIndex, messageContext);
triggerAfterCompletion(interceptorIndex, messageContext, null);
return responseExtractor.extractData(messageContext.getResponse());
}
else {
triggerHandleFault(interceptorIndex, messageContext);
triggerAfterCompletion(interceptorIndex, messageContext, null);
return (T)handleFault(connection, messageContext);
}
}
@@ -607,8 +610,19 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
}
}
catch (TransformerException ex) {
triggerAfterCompletion(interceptorIndex, messageContext, ex);
throw new WebServiceTransformerException("Transformation error: " + ex.getMessage(), ex);
}
catch (RuntimeException ex) {
// Trigger after-completion for thrown exception.
triggerAfterCompletion(interceptorIndex, messageContext, ex);
throw ex;
}
catch (IOException ex) {
// Trigger after-completion for thrown exception.
triggerAfterCompletion(interceptorIndex, messageContext, ex);
throw ex;
}
}
/** Sends the request in the given message context over the connection. */
@@ -758,6 +772,26 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
}
}
/**
* Trigger afterCompletion callbacks on the mapped ClientInterceptors. Will just
* invoke afterCompletion for all interceptors whose handleRequest invocation has
* successfully completed and returned true, in addition to the last interceptor who
* returned <code>false</code>.
* @param mappedEndpoint the mapped EndpointInvocationChain
* @param interceptorIndex index of last interceptor that successfully completed
* @param ex Exception thrown on handler execution, or <code>null</code> if none
* @see ClientInterceptor#afterCompletion
*/
private void triggerAfterCompletion(int interceptorIndex,
MessageContext messageContext, Exception ex)
throws WebServiceClientException {
if (interceptors != null) {
for (int i = interceptorIndex; i >= 0; i--) {
interceptors[i].afterCompletion(messageContext, ex);
}
}
}
/**
* Handles an fault in the given response message. The default implementation invokes the {@link
* FaultMessageResolver fault resolver} if registered, or invokes {@link #handleError(WebServiceConnection,

View File

@@ -257,7 +257,12 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
return true;
}
/**
/** Does nothing by default.*/
public void afterCompletion(MessageContext messageContext, Exception ex)
throws WebServiceClientException {
}
/**
* Abstract template method that returns the part of the request message that is to be validated.
*
* @param request the request message

View File

@@ -58,6 +58,8 @@ public interface ClientInterceptor {
/**
* Processes the incoming response message. Called for non-fault response messages before payload handling in the
* {@link org.springframework.ws.client.core.WebServiceTemplate}.
* <p/>
* Note: Will only be called if this interceptor's {@link #handleRequest} method has successfully completed.
*
* @param messageContext contains the outgoing request message
* @return <code>true</code> to continue processing of the request interceptors; <code>false</code> to indicate
@@ -70,6 +72,8 @@ public interface ClientInterceptor {
/**
* Processes the incoming response fault. Called for response fault messages before payload handling in the {@link
* org.springframework.ws.client.core.WebServiceTemplate}.
* <p/>
* Note: Will only be called if this interceptor's {@link #handleRequest} method has successfully completed.
*
* @param messageContext contains the outgoing request message
* @return <code>true</code> to continue processing of the request interceptors; <code>false</code> to indicate
@@ -80,4 +84,18 @@ public interface ClientInterceptor {
*/
boolean handleFault(MessageContext messageContext) throws WebServiceClientException;
/**
* Callback after completion of request and response (fault) processing. Will be called on any outcome, thus
* allows for proper resource cleanup.
* <p/>
* Note: Will only be called if this interceptor's {@link #handleRequest} method has successfully completed.
*
* @param messageContext contains both request and response messages, the response should contains a Fault
* @param ex exception thrown on handler execution, if any
* @throws WebServiceClientException in case of errors
* @since 2.2
*/
void afterCompletion(MessageContext messageContext, Exception ex) throws WebServiceClientException;
}

View File

@@ -378,6 +378,8 @@ public class WebServiceTemplateTest {
expect(interceptorMock2.handleRequest(isA(MessageContext.class))).andReturn(true);
expect(interceptorMock2.handleResponse(isA(MessageContext.class))).andReturn(true);
expect(interceptorMock1.handleResponse(isA(MessageContext.class))).andReturn(true);
interceptorMock2.afterCompletion(isA(MessageContext.class), (Exception)isNull());
interceptorMock1.afterCompletion(isA(MessageContext.class), (Exception)isNull());
WebServiceMessageCallback requestCallback = createMock(WebServiceMessageCallback.class);
requestCallback.doWithMessage(isA(WebServiceMessage.class));
@@ -409,6 +411,7 @@ public class WebServiceTemplateTest {
template.setInterceptors(new ClientInterceptor[]{interceptorMock1, interceptorMock2});
expect(interceptorMock1.handleRequest(isA(MessageContext.class))).andReturn(false);
expect(interceptorMock1.handleResponse(isA(MessageContext.class))).andReturn(true);
interceptorMock1.afterCompletion(isA(MessageContext.class), (Exception)isNull());
WebServiceMessageCallback requestCallback = createMock(WebServiceMessageCallback.class);
requestCallback.doWithMessage(messageContext.getRequest());
@@ -441,6 +444,7 @@ public class WebServiceTemplateTest {
template.setInterceptors(new ClientInterceptor[]{interceptorMock1, interceptorMock2});
expect(interceptorMock1.handleRequest(isA(MessageContext.class))).andReturn(false);
expect(interceptorMock1.handleResponse(isA(MessageContext.class))).andReturn(true);
interceptorMock1.afterCompletion(isA(MessageContext.class), (Exception)isNull());
WebServiceMessageCallback requestCallback = createMock(WebServiceMessageCallback.class);
requestCallback.doWithMessage(messageContext.getRequest());

View File

@@ -175,6 +175,7 @@ public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInter
return true;
}
public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) {
cleanUp();
}
@@ -252,7 +253,13 @@ public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInter
return true;
}
/**
@Override
public void afterCompletion(MessageContext messageContext, Exception ex)
throws WebServiceClientException {
cleanUp();
}
/**
* Handles an securement exception. Default implementation logs the given exception, and returns
* <code>false</code>.
*