diff --git a/core/src/main/java/org/springframework/ws/client/WebServiceFaultException.java b/core/src/main/java/org/springframework/ws/client/WebServiceFaultException.java
index 57e25e18..0042b3cb 100644
--- a/core/src/main/java/org/springframework/ws/client/WebServiceFaultException.java
+++ b/core/src/main/java/org/springframework/ws/client/WebServiceFaultException.java
@@ -16,18 +16,29 @@
package org.springframework.ws.client;
+import org.springframework.ws.WebServiceMessage;
+
/**
- * Thrown by SimpleFaultResolver when the response message has a fault.
+ * Thrown by SimpleFaultMessageResolver when the response message has a fault.
*
* @author Arjen Poutsma
*/
public class WebServiceFaultException extends WebServiceClientException {
- public WebServiceFaultException(String msg) {
- super(msg);
+ private final WebServiceMessage webServiceMessage;
+
+ /**
+ * Create a new instance of the WebServiceFaultException class.
+ *
+ * @param faultMessage the fault message
+ */
+ public WebServiceFaultException(WebServiceMessage faultMessage) {
+ super(faultMessage.getFaultReason());
+ webServiceMessage = faultMessage;
}
- public WebServiceFaultException(String msg, Throwable ex) {
- super(msg, ex);
+ /** Returns the fault message. */
+ public WebServiceMessage getWebServiceMessage() {
+ return webServiceMessage;
}
}
diff --git a/core/src/main/java/org/springframework/ws/client/core/FaultResolver.java b/core/src/main/java/org/springframework/ws/client/core/FaultMessageResolver.java
similarity index 86%
rename from core/src/main/java/org/springframework/ws/client/core/FaultResolver.java
rename to core/src/main/java/org/springframework/ws/client/core/FaultMessageResolver.java
index bcb8a6e8..97ca4ec9 100644
--- a/core/src/main/java/org/springframework/ws/client/core/FaultResolver.java
+++ b/core/src/main/java/org/springframework/ws/client/core/FaultMessageResolver.java
@@ -21,11 +21,11 @@ import java.io.IOException;
import org.springframework.ws.WebServiceMessage;
/**
- * Defines the interface for objects than can resolve faults in received {@link org.springframework.ws.WebServiceMessage}.
+ * Defines the interface for objects than can resolve fault {@link WebServiceMessage}.
*
* @author Arjen Poutsma
*/
-public interface FaultResolver {
+public interface FaultMessageResolver {
/**
* Try to resolve the given fault message that got received.
diff --git a/core/src/main/java/org/springframework/ws/client/core/SimpleFaultResolver.java b/core/src/main/java/org/springframework/ws/client/core/SimpleFaultMessageResolver.java
similarity index 74%
rename from core/src/main/java/org/springframework/ws/client/core/SimpleFaultResolver.java
rename to core/src/main/java/org/springframework/ws/client/core/SimpleFaultMessageResolver.java
index 40cd8dcf..7102d9e5 100644
--- a/core/src/main/java/org/springframework/ws/client/core/SimpleFaultResolver.java
+++ b/core/src/main/java/org/springframework/ws/client/core/SimpleFaultMessageResolver.java
@@ -20,16 +20,15 @@ import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.client.WebServiceFaultException;
/**
- * Simple fault resolver that simply throws a {@link org.springframework.ws.client.WebServiceFaultException} when a
- * fault occurs.
+ * Simple fault resolver that simply throws a {@link WebServiceFaultException} when a fault occurs.
*
* @author Arjen Poutsma
- * @see org.springframework.ws.client.WebServiceFaultException
+ * @see WebServiceFaultException
*/
-public class SimpleFaultResolver implements FaultResolver {
+public class SimpleFaultMessageResolver implements FaultMessageResolver {
/** Throws a new WebServiceFaultException. */
public void resolveFault(WebServiceMessage message) {
- throw new WebServiceFaultException(message.getFaultReason());
+ throw new WebServiceFaultException(message);
}
}
diff --git a/core/src/main/java/org/springframework/ws/client/core/WebServiceMessageCallback.java b/core/src/main/java/org/springframework/ws/client/core/WebServiceMessageCallback.java
index 7e360e2b..dbf06ec3 100644
--- a/core/src/main/java/org/springframework/ws/client/core/WebServiceMessageCallback.java
+++ b/core/src/main/java/org/springframework/ws/client/core/WebServiceMessageCallback.java
@@ -22,20 +22,20 @@ import org.springframework.ws.WebServiceMessage;
/**
* Generic callback interface for code that operates on a {@link WebServiceMessage}.
- *
- *
Implementations can execute any number of operations on the message, such as
- * set the contents of the message, or set the SOAPAction header.
+ *
SOAPAction header.
*
* @author Arjen Poutsma
*/
public interface WebServiceMessageCallback {
/**
- * Execute any number of operations on the supplied message.
+ * Execute any number of operations on the supplied message.
*
* @param message the message
* @throws IOException in case of I/O errors
*/
- void doInMessage(WebServiceMessage message) throws IOException;
+ void doWithMessage(WebServiceMessage message) throws IOException;
}
diff --git a/core/src/main/java/org/springframework/ws/client/core/WebServiceOperations.java b/core/src/main/java/org/springframework/ws/client/core/WebServiceOperations.java
index fe4a2910..ae844b21 100644
--- a/core/src/main/java/org/springframework/ws/client/core/WebServiceOperations.java
+++ b/core/src/main/java/org/springframework/ws/client/core/WebServiceOperations.java
@@ -166,9 +166,10 @@ public interface WebServiceOperations {
*
* @param requestPayload the payload of the request message
* @param responseResult the result to write the response payload to
+ * @return true if a response was received; false otherwise
* @throws WebServiceClientException if there is a problem sending or receiving the message
*/
- void sendAndReceive(Source requestPayload, Result responseResult) throws WebServiceClientException;
+ boolean sendAndReceive(Source requestPayload, Result responseResult) throws WebServiceClientException;
/**
* Sends a web service message that contains the given payload. Writes the response, if any, to the given
@@ -177,9 +178,10 @@ public interface WebServiceOperations {
* @param uri the URI to send the message to
* @param requestPayload the payload of the request message
* @param responseResult the result to write the response payload to
+ * @return true if a response was received; false otherwise
* @throws WebServiceClientException if there is a problem sending or receiving the message
*/
- void sendAndReceive(String uri, Source requestPayload, Result responseResult) throws WebServiceClientException;
+ boolean sendAndReceive(String uri, Source requestPayload, Result responseResult) throws WebServiceClientException;
/**
* Sends a web service message that contains the given payload. Writes the response, if any, to the given
@@ -192,9 +194,10 @@ public interface WebServiceOperations {
* @param requestPayload the payload of the request message
* @param requestCallback callback to change message, can be null
* @param responseResult the result to write the response payload to
+ * @return true if a response was received; false otherwise
* @throws WebServiceClientException if there is a problem sending or receiving the message
*/
- void sendAndReceive(Source requestPayload, WebServiceMessageCallback requestCallback, Result responseResult)
+ boolean sendAndReceive(Source requestPayload, WebServiceMessageCallback requestCallback, Result responseResult)
throws WebServiceClientException;
/**
@@ -207,12 +210,13 @@ public interface WebServiceOperations {
* @param requestPayload the payload of the request message
* @param requestCallback callback to change message, can be null
* @param responseResult the result to write the response payload to
+ * @return true if a response was received; false otherwise
* @throws WebServiceClientException if there is a problem sending or receiving the message
*/
- void sendAndReceive(String uri,
- Source requestPayload,
- WebServiceMessageCallback requestCallback,
- Result responseResult) throws WebServiceClientException;
+ boolean sendAndReceive(String uri,
+ Source requestPayload,
+ WebServiceMessageCallback requestCallback,
+ Result responseResult) throws WebServiceClientException;
/**
* Sends a web service message that can be manipulated with the given callback, reading the result with a
@@ -250,9 +254,10 @@ public interface WebServiceOperations {
*
* @param requestCallback the callback to be used for manipulating the request message
* @param responseCallback the callback to be used for manipulating the response message
+ * @return true if a response was received; false otherwise
* @throws WebServiceClientException if there is a problem sending or receiving the message
*/
- void sendAndReceive(WebServiceMessageCallback requestCallback, WebServiceMessageCallback responseCallback)
+ boolean sendAndReceive(WebServiceMessageCallback requestCallback, WebServiceMessageCallback responseCallback)
throws WebServiceClientException;
/**
@@ -262,9 +267,10 @@ public interface WebServiceOperations {
* @param uri the URI to send the message to
* @param requestCallback the callback to be used for manipulating the request message
* @param responseCallback the callback to be used for manipulating the response message
+ * @return true if a response was received; false otherwise
* @throws WebServiceClientException if there is a problem sending or receiving the message
*/
- void sendAndReceive(String uri,
- WebServiceMessageCallback requestCallback,
- WebServiceMessageCallback responseCallback) throws WebServiceClientException;
+ boolean sendAndReceive(String uri,
+ WebServiceMessageCallback requestCallback,
+ WebServiceMessageCallback responseCallback) throws WebServiceClientException;
}
diff --git a/core/src/main/java/org/springframework/ws/client/core/WebServiceTemplate.java b/core/src/main/java/org/springframework/ws/client/core/WebServiceTemplate.java
index 9af253b4..dc497333 100644
--- a/core/src/main/java/org/springframework/ws/client/core/WebServiceTemplate.java
+++ b/core/src/main/java/org/springframework/ws/client/core/WebServiceTemplate.java
@@ -18,7 +18,6 @@ package org.springframework.ws.client.core;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.util.Iterator;
import java.util.List;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
@@ -26,11 +25,7 @@ import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
-import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanInitializationException;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.oxm.Marshaller;
@@ -44,6 +39,7 @@ import org.springframework.ws.client.WebServiceIOException;
import org.springframework.ws.client.WebServiceTransformerException;
import org.springframework.ws.client.WebServiceTransportException;
import org.springframework.ws.client.support.WebServiceAccessor;
+import org.springframework.ws.soap.client.core.SoapFaultMessageResolver;
import org.springframework.ws.transport.FaultAwareWebServiceConnection;
import org.springframework.ws.transport.TransportException;
import org.springframework.ws.transport.WebServiceConnection;
@@ -51,31 +47,35 @@ import org.springframework.ws.transport.WebServiceMessageSender;
import org.springframework.ws.transport.context.DefaultTransportContext;
import org.springframework.ws.transport.context.TransportContext;
import org.springframework.ws.transport.context.TransportContextHolder;
+import org.springframework.ws.transport.http.HttpUrlConnectionMessageSender;
import org.springframework.ws.transport.support.DefaultStrategiesHelper;
/**
* The central class for client-side Web services. It provides a message-driven approach to sending and
- * receiving {@link org.springframework.ws.WebServiceMessage} instances.
+ * receiving {@link WebServiceMessage} instances.
*
* Code using this class need only implement callback interfaces, provide {@link Source} objects to read data from, or
* use the pluggable {@link Marshaller} support.
*
- * This template uses a {@link SimpleFaultResolver} to handle responses that contain faults.
+ * This template uses a {@link SoapFaultMessageResolver} to handle fault response messages. Another {@link
+ * FaultMessageResolver} can be defined with with {@link #setFaultMessageResolver(FaultMessageResolver)
+ * faultMessageResolver} property. If this property is set to null, no fault resolving is performed.
*
* @author Arjen Poutsma
*/
-public class WebServiceTemplate extends WebServiceAccessor implements WebServiceOperations, ApplicationContextAware {
+public class WebServiceTemplate extends WebServiceAccessor implements WebServiceOperations {
private Marshaller marshaller;
private Unmarshaller unmarshaller;
- private FaultResolver faultResolver = new SimpleFaultResolver();
+ private FaultMessageResolver faultMessageResolver;
private String defaultUri;
/** Creates a new WebServiceTemplate using default settings. */
public WebServiceTemplate() {
+ initDefaultStrategies();
}
/**
@@ -84,7 +84,9 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
* @param messageFactory the message factory to use
*/
public WebServiceTemplate(WebServiceMessageFactory messageFactory) {
+ this();
setMessageFactory(messageFactory);
+ afterPropertiesSet();
}
/** Returns the default URI to be used on operations that do not have a URI parameter. */
@@ -104,7 +106,7 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
* @see #sendAndReceive(WebServiceMessageCallback,WebServiceMessageCallback)
*/
public void setDefaultUri(String uri) {
- this.defaultUri = uri;
+ defaultUri = uri;
}
/** Returns the marshaller for this template. */
@@ -127,69 +129,60 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
this.unmarshaller = unmarshaller;
}
- /** Returns the fault resolver for this template. */
- public FaultResolver getFaultResolver() {
- return faultResolver;
+ /** Returns the fault message resolver for this template. */
+ public FaultMessageResolver getFaultMessageResolver() {
+ return faultMessageResolver;
}
- /** Sets the fault resolver for this template. */
- public void setFaultResolver(FaultResolver faultResolver) {
- Assert.notNull(faultResolver, "faultResolver must not be null");
- this.faultResolver = faultResolver;
+ /**
+ * Sets the fault resolver for this template. Default is the {@link SimpleFaultMessageResolver}, but may be set to
+ * null to disable fault handling.
+ */
+ public void setFaultMessageResolver(FaultMessageResolver faultMessageResolver) {
+ this.faultMessageResolver = faultMessageResolver;
}
- public final void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ /**
+ * Initialize the default implementations for the template's strategies: {@link SoapFaultMessageResolver}, {@link
+ * org.springframework.ws.soap.saaj.SaajSoapMessageFactory}, and {@link HttpUrlConnectionMessageSender}.
+ *
+ * @throws BeanInitializationException in case of initalization errors
+ * @see #setFaultMessageResolver(FaultMessageResolver)
+ * @see #setMessageFactory(WebServiceMessageFactory)
+ * @see #setMessageSender(WebServiceMessageSender)
+ */
+ protected void initDefaultStrategies() {
Resource resource = new ClassPathResource(ClassUtils.getShortName(getClass()) + ".properties", getClass());
- DefaultStrategiesHelper defaultStrategiesHelper = new DefaultStrategiesHelper(resource);
+ DefaultStrategiesHelper strategiesHelper = new DefaultStrategiesHelper(resource);
if (getMessageFactory() == null) {
- initWebServiceMessageFactory(defaultStrategiesHelper, applicationContext);
+ initMessageFactory(strategiesHelper);
}
if (ObjectUtils.isEmpty(getMessageSenders())) {
- initWebServiceMessageSenders(defaultStrategiesHelper, applicationContext);
+ initMessageSenders(strategiesHelper);
+ }
+ if (getFaultMessageResolver() == null) {
+ initFaultMessageResolver(strategiesHelper);
}
}
- private void initWebServiceMessageFactory(DefaultStrategiesHelper defaultStrategiesHelper,
- ApplicationContext applicationContext)
- throws BeanInitializationException {
- WebServiceMessageFactory messageFactory = (WebServiceMessageFactory) defaultStrategiesHelper
- .getDefaultStrategy(WebServiceMessageFactory.class, applicationContext);
- if (logger.isInfoEnabled()) {
- logger.info("Using default message factory [" + messageFactory + "]");
- }
- if (messageFactory instanceof InitializingBean) {
- try {
- ((InitializingBean) messageFactory).afterPropertiesSet();
- }
- catch (Exception ex) {
- throw new BeanInitializationException("Could not initialize message factory", ex);
- }
- }
+ private void initMessageFactory(DefaultStrategiesHelper helper) throws BeanInitializationException {
+ WebServiceMessageFactory messageFactory = (WebServiceMessageFactory) helper
+ .getDefaultStrategy(WebServiceMessageFactory.class);
setMessageFactory(messageFactory);
}
- private void initWebServiceMessageSenders(DefaultStrategiesHelper defaultStrategiesHelper,
- ApplicationContext applicationContext) {
- List messageSenders =
- defaultStrategiesHelper.getDefaultStrategies(WebServiceMessageSender.class, applicationContext);
- if (logger.isInfoEnabled()) {
- logger.info("Using default message senders " + messageSenders);
- }
- for (Iterator iterator = messageSenders.iterator(); iterator.hasNext();) {
- WebServiceMessageSender messageSender = (WebServiceMessageSender) iterator.next();
- if (messageSender instanceof InitializingBean) {
- try {
- ((InitializingBean) messageSender).afterPropertiesSet();
- }
- catch (Exception ex) {
- throw new BeanInitializationException("Could not initialize message factory", ex);
- }
- }
- }
+ private void initMessageSenders(DefaultStrategiesHelper helper) {
+ List messageSenders = helper.getDefaultStrategies(WebServiceMessageSender.class);
setMessageSenders(
(WebServiceMessageSender[]) messageSenders.toArray(new WebServiceMessageSender[messageSenders.size()]));
}
+ private void initFaultMessageResolver(DefaultStrategiesHelper helper) throws BeanInitializationException {
+ FaultMessageResolver faultMessageResolver =
+ (FaultMessageResolver) helper.getDefaultStrategy(FaultMessageResolver.class);
+ setFaultMessageResolver(faultMessageResolver);
+ }
+
/*
* Marshalling methods
*/
@@ -217,10 +210,10 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
}
return sendAndReceive(uri, new WebServiceMessageCallback() {
- public void doInMessage(WebServiceMessage message) throws IOException {
+ public void doWithMessage(WebServiceMessage message) throws IOException {
getMarshaller().marshal(requestPayload, message.getPayloadResult());
if (requestCallback != null) {
- requestCallback.doInMessage(message);
+ requestCallback.doWithMessage(message);
}
}
}, new WebServiceMessageExtractor() {
@@ -235,38 +228,40 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
* Result-handling methods
*/
- public void sendAndReceive(Source requestPayload, Result responseResult) {
- sendAndReceive(requestPayload, null, responseResult);
+ public boolean sendAndReceive(Source requestPayload, Result responseResult) {
+ return sendAndReceive(requestPayload, null, responseResult);
}
- public void sendAndReceive(String uri, Source requestPayload, Result responseResult) {
- sendAndReceive(uri, requestPayload, null, responseResult);
+ public boolean sendAndReceive(String uri, Source requestPayload, Result responseResult) {
+ return sendAndReceive(uri, requestPayload, null, responseResult);
}
- public void sendAndReceive(Source requestPayload,
- WebServiceMessageCallback requestCallback,
- final Result responseResult) {
- sendAndReceive(getDefaultUri(), requestPayload, requestCallback, responseResult);
+ public boolean sendAndReceive(Source requestPayload,
+ WebServiceMessageCallback requestCallback,
+ final Result responseResult) {
+ return sendAndReceive(getDefaultUri(), requestPayload, requestCallback, responseResult);
}
- public void sendAndReceive(String uri,
- Source requestPayload,
- WebServiceMessageCallback requestCallback,
- final Result responseResult) {
+ public boolean sendAndReceive(String uri,
+ Source requestPayload,
+ WebServiceMessageCallback requestCallback,
+ final Result responseResult) {
try {
final Transformer transformer = createTransformer();
- doSendAndReceive(uri, transformer, requestPayload, requestCallback, new SourceExtractor() {
+ Boolean retVal = (Boolean) doSendAndReceive(uri, transformer, requestPayload, requestCallback,
+ new SourceExtractor() {
- public Object extractData(Source source) throws IOException {
- try {
- transformer.transform(source, responseResult);
- }
- catch (TransformerException ex) {
- throw new WebServiceTransformerException("Could not transform payload", ex);
- }
- return null;
- }
- });
+ public Object extractData(Source source) throws IOException {
+ try {
+ transformer.transform(source, responseResult);
+ }
+ catch (TransformerException ex) {
+ throw new WebServiceTransformerException("Could not transform payload", ex);
+ }
+ return Boolean.TRUE;
+ }
+ });
+ return retVal != null && retVal.booleanValue();
}
catch (TransformerConfigurationException ex) {
throw new WebServiceTransformerException("Could not create transformer", ex);
@@ -311,11 +306,11 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
final SourceExtractor responseExtractor) {
Assert.notNull(responseExtractor, "responseExtractor must not be null");
return sendAndReceive(uri, new WebServiceMessageCallback() {
- public void doInMessage(WebServiceMessage message) throws IOException {
+ public void doWithMessage(WebServiceMessage message) throws IOException {
try {
transformer.transform(requestPayload, message.getPayloadResult());
if (requestCallback != null) {
- requestCallback.doInMessage(message);
+ requestCallback.doWithMessage(message);
}
}
catch (TransformerException ex) {
@@ -329,16 +324,18 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
* WebServiceMessage-handling methods
*/
- public void sendAndReceive(WebServiceMessageCallback requestCallback, WebServiceMessageCallback responseCallback) {
- Assert.notNull(responseCallback, "responseCallback must not be null");
- sendAndReceive(requestCallback, new WebServiceMessageCallbackMessageExtractor(responseCallback));
+ public boolean sendAndReceive(WebServiceMessageCallback requestCallback,
+ WebServiceMessageCallback responseCallback) {
+ return sendAndReceive(getDefaultUri(), requestCallback, responseCallback);
}
- public void sendAndReceive(String uri,
- WebServiceMessageCallback requestCallback,
- WebServiceMessageCallback responseCallback) {
+ public boolean sendAndReceive(String uri,
+ WebServiceMessageCallback requestCallback,
+ WebServiceMessageCallback responseCallback) {
Assert.notNull(responseCallback, "responseCallback must not be null");
- sendAndReceive(uri, requestCallback, new WebServiceMessageCallbackMessageExtractor(responseCallback));
+ Boolean result = (Boolean) sendAndReceive(uri, requestCallback,
+ new WebServiceMessageCallbackMessageExtractor(responseCallback));
+ return result != null && result.booleanValue();
}
public Object sendAndReceive(WebServiceMessageCallback requestCallback,
@@ -358,21 +355,26 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
TransportContextHolder.setTransportContext(new DefaultTransportContext(connection));
WebServiceMessage request = getMessageFactory().createWebServiceMessage();
if (requestCallback != null) {
- requestCallback.doInMessage(request);
+ requestCallback.doWithMessage(request);
}
sendRequest(connection, request);
- WebServiceMessage response = receiveResponse(connection);
+ if (connection.hasError()) {
+ return handleError(connection, request);
+ }
+ WebServiceMessage response = connection.receive(getMessageFactory());
if (response != null) {
- if (!hasFault(connection, response)) {
- // normal response
- return responseExtractor.extractData(response);
+ if (hasFault(connection, response)) {
+ return handleFault(connection, request, response);
}
else {
- // fault response
- getFaultResolver().resolveFault(response);
+ logResponse(request, response);
+ return responseExtractor.extractData(response);
}
}
- return null;
+ else {
+ logger.debug("Received no response for request [" + request + "]");
+ return null;
+ }
}
catch (TransportException ex) {
throw new WebServiceTransportException("Could not use transport: " + ex.getMessage(), ex);
@@ -393,6 +395,63 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
}
}
+ /**
+ * Determines whether the given connection or message context has a fault. Default implementation checks whether the
+ * connection is a {@link FaultAwareWebServiceConnection}, and calls returns {@link
+ * FaultAwareWebServiceConnection#hasFault()} if so. Otherwise, {@link WebServiceMessage#hasFault()} is returned
+ * (which required a full message parse).
+ *
+ * @param connection the connection (possibly a {@link FaultAwareWebServiceConnection}
+ * @param response the response message
+ * @return true if either the connection or the message has a fault; false otherwise
+ * @throws IOException in case of I/O errors
+ */
+ protected boolean hasFault(WebServiceConnection connection, WebServiceMessage response) throws IOException {
+ if (connection instanceof FaultAwareWebServiceConnection) {
+ return ((FaultAwareWebServiceConnection) connection).hasFault();
+ }
+ else {
+ return response.hasFault();
+ }
+ }
+
+ /**
+ * Handles an error on the given connection. The default implementation throws a {@link
+ * WebServiceTransportException}.
+ *
+ * @param connection the erronous connection
+ * @param request the corresponding request message
+ * @return the object to be returned from {@link #sendAndReceive(String,WebServiceMessageCallback,
+ *WebServiceMessageExtractor)}, if any
+ */
+ protected Object handleError(WebServiceConnection connection, WebServiceMessage request) throws IOException {
+ logger.debug("Received " + connection.getErrorMessage() + " error for request [" + request + "]");
+ throw new WebServiceTransportException(connection.getErrorMessage());
+ }
+
+ /**
+ * Handles an fault in the given response message. The default implementation invokes the {@link
+ * FaultMessageResolver fault resolver} if registered, or invokes {@link #handleError(WebServiceConnection,
+ *WebServiceMessage)} otherwise.
+ *
+ * @param connection the erronous connection
+ * @param request the corresponding request message
+ * @param response the fault response message
+ * @return the object to be returned from {@link #sendAndReceive(String,WebServiceMessageCallback,
+ *WebServiceMessageExtractor)}, if any
+ */
+ protected Object handleFault(WebServiceConnection connection, WebServiceMessage request, WebServiceMessage response)
+ throws IOException {
+ if (getFaultMessageResolver() != null) {
+ logger.debug("Received Fault message for request [" + request + "]");
+ getFaultMessageResolver().resolveFault(response);
+ return null;
+ }
+ else {
+ return handleError(connection, request);
+ }
+ }
+
/** Sends the request in the given message context over the connection. */
private void sendRequest(WebServiceConnection connection, WebServiceMessage request) throws IOException {
if (logger.isTraceEnabled()) {
@@ -406,31 +465,17 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
connection.send(request);
}
- private WebServiceMessage receiveResponse(WebServiceConnection connection) throws IOException {
- WebServiceMessage response = connection.receive(getMessageFactory());
- if (response != null) {
- if (logger.isTraceEnabled()) {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- response.writeTo(os);
- logger.trace("WebServiceTemplate receives response [" + os.toString("UTF-8") + "]");
- }
- else if (logger.isDebugEnabled()) {
- logger.debug("WebServiceTemplate receives response [" + response + "]");
- }
+ private void logResponse(WebServiceMessage request, WebServiceMessage response) throws IOException {
+ if (logger.isTraceEnabled()) {
+ ByteArrayOutputStream requestStream = new ByteArrayOutputStream();
+ request.writeTo(requestStream);
+ ByteArrayOutputStream responseStream = new ByteArrayOutputStream();
+ response.writeTo(responseStream);
+ logger.trace("Received response [" + responseStream.toString("UTF-8") + "] for request [" +
+ requestStream.toString("UTF-8") + "]");
}
else if (logger.isDebugEnabled()) {
- logger.debug("WebServiceTemplate receives no response");
- }
- return response;
- }
-
- /** Determines whether the given connection or message context has a fault. */
- private boolean hasFault(WebServiceConnection connection, WebServiceMessage response) throws IOException {
- if (connection instanceof FaultAwareWebServiceConnection) {
- return ((FaultAwareWebServiceConnection) connection).hasFault();
- }
- else {
- return response.hasFault();
+ logger.debug("Received response [" + response + "] for request [" + request + "]");
}
}
@@ -444,8 +489,8 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
}
public Object extractData(WebServiceMessage message) throws IOException {
- callback.doInMessage(message);
- return null;
+ callback.doWithMessage(message);
+ return Boolean.TRUE;
}
}
diff --git a/core/src/main/java/org/springframework/ws/client/core/support/WebServiceGatewaySupport.java b/core/src/main/java/org/springframework/ws/client/core/support/WebServiceGatewaySupport.java
index 6a850b6a..22d348c5 100644
--- a/core/src/main/java/org/springframework/ws/client/core/support/WebServiceGatewaySupport.java
+++ b/core/src/main/java/org/springframework/ws/client/core/support/WebServiceGatewaySupport.java
@@ -18,10 +18,7 @@ package org.springframework.ws.client.core.support;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;
import org.springframework.util.Assert;
@@ -44,7 +41,7 @@ import org.springframework.ws.transport.WebServiceMessageSender;
* @see org.springframework.ws.client.core.WebServiceTemplate
* @see #setMarshaller(org.springframework.oxm.Marshaller)
*/
-public abstract class WebServiceGatewaySupport implements InitializingBean, ApplicationContextAware {
+public abstract class WebServiceGatewaySupport implements InitializingBean {
/** Logger available to subclasses. */
protected final Log logger = LogFactory.getLog(getClass());
@@ -144,10 +141,6 @@ public abstract class WebServiceGatewaySupport implements InitializingBean, Appl
webServiceTemplate.setUnmarshaller(unmarshaller);
}
- public final void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- webServiceTemplate.setApplicationContext(applicationContext);
- }
-
public final void afterPropertiesSet() throws Exception {
webServiceTemplate.afterPropertiesSet();
initGateway();
diff --git a/core/src/main/java/org/springframework/ws/client/support/WebServiceAccessor.java b/core/src/main/java/org/springframework/ws/client/support/WebServiceAccessor.java
index 816d63bb..3b8faf4c 100644
--- a/core/src/main/java/org/springframework/ws/client/support/WebServiceAccessor.java
+++ b/core/src/main/java/org/springframework/ws/client/support/WebServiceAccessor.java
@@ -64,7 +64,7 @@ public abstract class WebServiceAccessor extends TransformerObjectSupport implem
*/
public void setMessageSender(WebServiceMessageSender messageSender) {
Assert.notNull(messageSender, "'messageSender' must not be null");
- this.messageSenders = new WebServiceMessageSender[]{messageSender};
+ messageSenders = new WebServiceMessageSender[]{messageSender};
}
/**
@@ -79,7 +79,7 @@ public abstract class WebServiceAccessor extends TransformerObjectSupport implem
this.messageSenders = messageSenders;
}
- public void afterPropertiesSet() throws Exception {
+ public void afterPropertiesSet() {
Assert.notNull(getMessageFactory(), "Property 'messageFactory' is required");
Assert.notEmpty(getMessageSenders(), "Property 'messageSenders' is required");
}
diff --git a/core/src/main/java/org/springframework/ws/pox/dom/DomPoxMessage.java b/core/src/main/java/org/springframework/ws/pox/dom/DomPoxMessage.java
index 5cefbff0..5b94b92d 100644
--- a/core/src/main/java/org/springframework/ws/pox/dom/DomPoxMessage.java
+++ b/core/src/main/java/org/springframework/ws/pox/dom/DomPoxMessage.java
@@ -26,9 +26,13 @@ import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
+import org.springframework.util.Assert;
import org.springframework.ws.pox.PoxMessage;
+import org.springframework.ws.transport.TransportConstants;
import org.springframework.ws.transport.TransportOutputStream;
+import org.springframework.xml.namespace.QNameUtils;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
/**
* Implementation of the PoxMessage interface that is based on a DOM Document.
@@ -38,25 +42,27 @@ import org.w3c.dom.Document;
*/
public class DomPoxMessage implements PoxMessage {
- private static final String CONTENT_TYPE = "text/xml";
+ private final String contentType;
private final Document document;
- private Transformer transformer;
+ private final Transformer transformer;
/**
* Constructs a new instance of the DomPoxMessage with the given document.
*
* @param document the document to base the message on
*/
- public DomPoxMessage(Document document, Transformer transformer) {
+ public DomPoxMessage(Document document, Transformer transformer, String contentType) {
+ Assert.notNull(document, "'document' must not be null");
+ Assert.notNull(transformer, "'transformer' must not be null");
+ Assert.hasLength(contentType, "'contentType' must not be empty");
this.document = document;
this.transformer = transformer;
+ this.contentType = contentType;
}
- /**
- * Returns the document underlying this message.
- */
+ /** Returns the document underlying this message. */
public Document getDocument() {
return document;
}
@@ -77,11 +83,21 @@ public class DomPoxMessage implements PoxMessage {
return null;
}
+ public String toString() {
+ StringBuffer buffer = new StringBuffer("DomPoxMessage ");
+ Element root = document.getDocumentElement();
+ if (root != null) {
+ buffer.append(' ');
+ buffer.append(QNameUtils.getQNameForNode(root));
+ }
+ return buffer.toString();
+ }
+
public void writeTo(OutputStream outputStream) throws IOException {
try {
if (outputStream instanceof TransportOutputStream) {
TransportOutputStream transportOutputStream = (TransportOutputStream) outputStream;
- transportOutputStream.addHeader("Content-Type", CONTENT_TYPE);
+ transportOutputStream.addHeader(TransportConstants.HEADER_CONTENT_TYPE, contentType);
}
transformer.transform(getPayloadSource(), new StreamResult(outputStream));
}
diff --git a/core/src/main/java/org/springframework/ws/pox/dom/DomPoxMessageFactory.java b/core/src/main/java/org/springframework/ws/pox/dom/DomPoxMessageFactory.java
index b12d5aee..ac303687 100644
--- a/core/src/main/java/org/springframework/ws/pox/dom/DomPoxMessageFactory.java
+++ b/core/src/main/java/org/springframework/ws/pox/dom/DomPoxMessageFactory.java
@@ -22,57 +22,56 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerFactory;
-import org.springframework.beans.factory.InitializingBean;
+import org.springframework.util.Assert;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
+import org.springframework.xml.transform.TransformerObjectSupport;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
/**
- * Implementation of the {@link org.springframework.ws.WebServiceMessageFactory WebServiceMessageFactory} interinterface
- * that creates a DOM PoxMessage.
+ * Implementation of the {@link WebServiceMessageFactory} interinterface that creates a {@link DomPoxMessage}.
*
* @author Arjen Poutsma
* @see org.springframework.ws.pox.dom.DomPoxMessage
*/
-public class DomPoxMessageFactory implements WebServiceMessageFactory, InitializingBean {
+public class DomPoxMessageFactory extends TransformerObjectSupport implements WebServiceMessageFactory {
- private DocumentBuilderFactory documentBuilderFactory;
+ /** The default content type for the POX messages. */
+ public static final String DEFAULT_CONTENT_TYPE = "application/xml";
- private boolean namespaceAware = true;
+ private DocumentBuilderFactory documentBuilderFactory =
+ documentBuilderFactory = DocumentBuilderFactory.newInstance();
- private TransformerFactory transformerFactory;
+ private String contentType = DEFAULT_CONTENT_TYPE;
- private boolean validating = false;
+ public DomPoxMessageFactory() {
+ documentBuilderFactory.setNamespaceAware(true);
+ documentBuilderFactory.setValidating(false);
+ }
- /**
- * Set whether or not the XML parser should be XML namespace aware. Default is true.
- */
+ /** Sets the content-type for the {@link DomPoxMessage}. */
+ public void setContentType(String contentType) {
+ Assert.hasLength(contentType, "'contentType' must not be empty");
+ this.contentType = contentType;
+ }
+
+ /** Set whether or not the XML parser should be XML namespace aware. Default is true. */
public void setNamespaceAware(boolean namespaceAware) {
- this.namespaceAware = namespaceAware;
- }
-
- /**
- * Set if the XML parser should validate the document. Default is false.
- */
- public void setValidating(boolean validating) {
- this.validating = validating;
- }
-
- public void afterPropertiesSet() throws Exception {
- documentBuilderFactory = DocumentBuilderFactory.newInstance();
- documentBuilderFactory.setValidating(validating);
documentBuilderFactory.setNamespaceAware(namespaceAware);
- transformerFactory = TransformerFactory.newInstance();
+ }
+
+ /** Set if the XML parser should validate the document. Default is false. */
+ public void setValidating(boolean validating) {
+ documentBuilderFactory.setValidating(validating);
}
public WebServiceMessage createWebServiceMessage() {
try {
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document request = documentBuilder.newDocument();
- return new DomPoxMessage(request, transformerFactory.newTransformer());
+ return new DomPoxMessage(request, createTransformer(), contentType);
}
catch (ParserConfigurationException ex) {
throw new DomPoxMessageException("Could not create message context", ex);
@@ -86,7 +85,7 @@ public class DomPoxMessageFactory implements WebServiceMessageFactory, Initializ
try {
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document request = documentBuilder.parse(inputStream);
- return new DomPoxMessage(request, transformerFactory.newTransformer());
+ return new DomPoxMessage(request, createTransformer(), contentType);
}
catch (ParserConfigurationException ex) {
throw new DomPoxMessageException("Could not create message context", ex);
diff --git a/core/src/main/java/org/springframework/ws/server/MessageDispatcher.java b/core/src/main/java/org/springframework/ws/server/MessageDispatcher.java
index e12f8e44..8c2f8219 100644
--- a/core/src/main/java/org/springframework/ws/server/MessageDispatcher.java
+++ b/core/src/main/java/org/springframework/ws/server/MessageDispatcher.java
@@ -51,22 +51,17 @@ import org.springframework.ws.transport.support.DefaultStrategiesHelper;
/**
* Central dispatcher for use within Spring-WS, dispatching Web service messages to registered endpoints.
*
- * This dispatcher is quite similar to Spring MVCs {@link DispatcherServlet}. Just like its counterpart, this
- * dispatcher is very flexible. This class is SOAP agnostic; in typical SOAP Web Services, the
- * {@link SoapMessageDispatcher} subclass is used.
- * endpointMappings property.endpointAdapters property.endpointExceptionResolvers property.endpointMappings property.endpointAdapters property.endpointExceptionResolvers property.QName representing the fault code
- */
+ /** Returns the fault code. */
QName getFaultCode();
/**
@@ -39,14 +35,10 @@ public interface SoapFault extends SoapElement {
*/
String getFaultStringOrReason();
- /**
- * Returns the fault actor or role. For SOAP 1.1, this returns the actor. For SOAP 1.2, this returns the role.
- */
+ /** Returns the fault actor or role. For SOAP 1.1, this returns the actor. For SOAP 1.2, this returns the role. */
String getFaultActorOrRole();
- /**
- * Sets the fault actor. For SOAP 1.1, this sets the actor. For SOAP 1.2, this sets the role.
- */
+ /** Sets the fault actor. For SOAP 1.1, this sets the actor. For SOAP 1.2, this sets the role. */
void setFaultActorOrRole(String faultActor);
/**
diff --git a/core/src/main/java/org/springframework/ws/soap/client/SoapFaultClientException.java b/core/src/main/java/org/springframework/ws/soap/client/SoapFaultClientException.java
new file mode 100644
index 00000000..a2ce72e7
--- /dev/null
+++ b/core/src/main/java/org/springframework/ws/soap/client/SoapFaultClientException.java
@@ -0,0 +1,67 @@
+/*
+ * 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.client;
+
+import javax.xml.namespace.QName;
+
+import org.springframework.ws.client.WebServiceFaultException;
+import org.springframework.ws.soap.SoapBody;
+import org.springframework.ws.soap.SoapFault;
+import org.springframework.ws.soap.SoapMessage;
+
+/**
+ * Thrown by SoapFaultMessageResolver when the response message has a fault.
+ *
+ * @author Arjen Poutsma
+ */
+public class SoapFaultClientException extends WebServiceFaultException {
+
+ private final SoapFault soapFault;
+
+ /**
+ * Create a new instance of the SoapFaultClientException class.
+ *
+ * @param faultMessage the fault message
+ */
+ public SoapFaultClientException(SoapMessage faultMessage) {
+ super(faultMessage);
+ SoapBody body = faultMessage.getSoapBody();
+ soapFault = body != null ? body.getFault() : null;
+ }
+
+ /** Returns the {@link SoapFault}. */
+ public SoapFault getSoapFault() {
+ return soapFault;
+ }
+
+ /** Returns the fault code. */
+ public QName getFaultCode() {
+ return soapFault != null ? soapFault.getFaultCode() : null;
+ }
+
+ /**
+ * Returns the fault string or reason. For SOAP 1.1, this returns the fault string. For SOAP 1.2, this returns the
+ * fault reason for the default locale.
+ *
+ * Note that this message returns the same as {@link #getMessage()}.
+ */
+ public String getFaultStringOrReason() {
+ return soapFault != null ? soapFault.getFaultStringOrReason() : null;
+ }
+
+
+}
diff --git a/core/src/main/java/org/springframework/ws/client/core/support/SoapActionCallback.java b/core/src/main/java/org/springframework/ws/soap/client/core/SoapActionCallback.java
similarity index 87%
rename from core/src/main/java/org/springframework/ws/client/core/support/SoapActionCallback.java
rename to core/src/main/java/org/springframework/ws/soap/client/core/SoapActionCallback.java
index dc7d9e69..66a01077 100644
--- a/core/src/main/java/org/springframework/ws/client/core/support/SoapActionCallback.java
+++ b/core/src/main/java/org/springframework/ws/soap/client/core/SoapActionCallback.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package org.springframework.ws.client.core.support;
+package org.springframework.ws.soap.client.core;
import java.io.IOException;
@@ -40,14 +40,12 @@ public class SoapActionCallback implements WebServiceMessageCallback {
private final String soapAction;
- /**
- * Create a new SoapActionCallback with the given string SOAPAction.
- */
+ /** Create a new SoapActionCallback with the given string SOAPAction. */
public SoapActionCallback(String soapAction) {
this.soapAction = soapAction;
}
- public void doInMessage(WebServiceMessage message) throws IOException {
+ public void doWithMessage(WebServiceMessage message) throws IOException {
SoapMessage soapMessage = (SoapMessage) message;
soapMessage.setSoapAction(soapAction);
}
diff --git a/core/src/main/java/org/springframework/ws/soap/client/core/SoapFaultMessageResolver.java b/core/src/main/java/org/springframework/ws/soap/client/core/SoapFaultMessageResolver.java
new file mode 100644
index 00000000..4335689a
--- /dev/null
+++ b/core/src/main/java/org/springframework/ws/soap/client/core/SoapFaultMessageResolver.java
@@ -0,0 +1,38 @@
+/*
+ * 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.client.core;
+
+import java.io.IOException;
+
+import org.springframework.ws.WebServiceMessage;
+import org.springframework.ws.client.core.FaultMessageResolver;
+import org.springframework.ws.soap.SoapMessage;
+import org.springframework.ws.soap.client.SoapFaultClientException;
+
+/**
+ * Simple fault resolver that simply throws a {@link SoapFaultClientException} when a fault occurs.
+ *
+ * @author Arjen Poutsma
+ * @see SoapFaultClientException
+ */
+public class SoapFaultMessageResolver implements FaultMessageResolver {
+
+ public void resolveFault(WebServiceMessage message) throws IOException {
+ SoapMessage soapMessage = (SoapMessage) message;
+ throw new SoapFaultClientException(soapMessage);
+ }
+}
diff --git a/core/src/main/java/org/springframework/ws/soap/client/core/package.html b/core/src/main/java/org/springframework/ws/soap/client/core/package.html
new file mode 100644
index 00000000..5cee2505
--- /dev/null
+++ b/core/src/main/java/org/springframework/ws/soap/client/core/package.html
@@ -0,0 +1,5 @@
+
+
+Contains core classes for SOAP-specific client-side Spring-WS support.
+
+
diff --git a/core/src/main/java/org/springframework/ws/soap/client/package.html b/core/src/main/java/org/springframework/ws/soap/client/package.html
new file mode 100644
index 00000000..8525972d
--- /dev/null
+++ b/core/src/main/java/org/springframework/ws/soap/client/package.html
@@ -0,0 +1,5 @@
+
+
+Contains classes for SOAP-specific client-side Spring-WS support.
+
+
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapMessageFactory.java b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapMessageFactory.java
index 9f6bdea0..e0d083f4 100644
--- a/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapMessageFactory.java
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapMessageFactory.java
@@ -130,8 +130,8 @@ public class SaajSoapMessageFactory implements SoapMessageFactory, InitializingB
throw new SoapMessageCreationException("Could not create SAAJ MessageFactory: " + ex.getMessage(), ex);
}
}
- if (logger.isDebugEnabled()) {
- logger.debug("Using MessageFactory class [" + messageFactory.getClass().getName() + "]");
+ if (logger.isTraceEnabled()) {
+ logger.trace("Using MessageFactory class [" + messageFactory.getClass().getName() + "]");
}
}
diff --git a/core/src/main/java/org/springframework/ws/transport/FaultAwareWebServiceConnection.java b/core/src/main/java/org/springframework/ws/transport/FaultAwareWebServiceConnection.java
index d9f81edd..d4122a9d 100644
--- a/core/src/main/java/org/springframework/ws/transport/FaultAwareWebServiceConnection.java
+++ b/core/src/main/java/org/springframework/ws/transport/FaultAwareWebServiceConnection.java
@@ -19,15 +19,16 @@ package org.springframework.ws.transport;
import java.io.IOException;
/**
- * Sub-interface of {@link WebServiceConnection} that is aware of any SOAP Faults received. Typically, fault detection
- * is done by inspecting connection error codes, etc.
+ * Sub-interface of {@link WebServiceConnection} that is aware of any Fault messages received. Fault messages (such as
+ * SOAP Faults often require different processing rules. Typically, fault detection is done by inspecting connection
+ * error codes, etc.
*
* @author Arjen Poutsma
*/
public interface FaultAwareWebServiceConnection extends WebServiceConnection {
/**
- * Indicates whether this connection has a SOAP Fault.
+ * Indicates whether this connection has a Fault.
*
* @return true if this connection has a fault; false otherwise.
*/
diff --git a/core/src/main/java/org/springframework/ws/transport/WebServiceConnection.java b/core/src/main/java/org/springframework/ws/transport/WebServiceConnection.java
index 7ac0d1ba..db7068a3 100644
--- a/core/src/main/java/org/springframework/ws/transport/WebServiceConnection.java
+++ b/core/src/main/java/org/springframework/ws/transport/WebServiceConnection.java
@@ -50,6 +50,22 @@ public interface WebServiceConnection {
*/
WebServiceMessage receive(WebServiceMessageFactory messageFactory) throws IOException;
+ /**
+ * Indicates whether this connection has an error. Typically, error detection is done by inspecting connection error
+ * codes, etc.
+ *
+ * @return true if this connection has an error; false otherwise.
+ */
+ boolean hasError() throws IOException;
+
+ /**
+ * Returns the error message.
+ *
+ * @return the connection error message, if any; returns null when no error is present
+ * @see #hasError()
+ */
+ String getErrorMessage() throws IOException;
+
/**
* Closes this connection.
*
diff --git a/core/src/main/java/org/springframework/ws/transport/http/AbstractHttpSenderConnection.java b/core/src/main/java/org/springframework/ws/transport/http/AbstractHttpSenderConnection.java
index c5a4984d..cd4c87ca 100644
--- a/core/src/main/java/org/springframework/ws/transport/http/AbstractHttpSenderConnection.java
+++ b/core/src/main/java/org/springframework/ws/transport/http/AbstractHttpSenderConnection.java
@@ -39,7 +39,7 @@ public abstract class AbstractHttpSenderConnection extends AbstractSenderConnect
protected static final String ENCODING_GZIP = "gzip";
- protected static final int HTTP_STATUS_INTERNAL_ERROR = 500;
+ protected static final int HTTP_STATUS_INTERNAL_SERVER_ERROR = 500;
/** Buffer used for reading the response, when the content length is invalid. */
private byte[] responseBuffer;
@@ -55,8 +55,13 @@ public abstract class AbstractHttpSenderConnection extends AbstractSenderConnect
return contentLength > 0;
}
+ public final boolean hasError() throws IOException {
+ int code = getResponseCode();
+ return code / 100 != 2 && code != HTTP_STATUS_INTERNAL_SERVER_ERROR;
+ }
+
public final boolean hasFault() throws IOException {
- return getResponseCode() == HTTP_STATUS_INTERNAL_ERROR;
+ return getResponseCode() == HTTP_STATUS_INTERNAL_SERVER_ERROR;
}
protected final InputStream getResponseInputStream() throws IOException {
diff --git a/core/src/main/java/org/springframework/ws/transport/http/CommonsHttpConnection.java b/core/src/main/java/org/springframework/ws/transport/http/CommonsHttpConnection.java
index a2fe6687..fe91ca35 100644
--- a/core/src/main/java/org/springframework/ws/transport/http/CommonsHttpConnection.java
+++ b/core/src/main/java/org/springframework/ws/transport/http/CommonsHttpConnection.java
@@ -25,7 +25,6 @@ import java.util.Iterator;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.springframework.util.Assert;
@@ -57,6 +56,10 @@ public class CommonsHttpConnection extends AbstractHttpSenderConnection {
return postMethod;
}
+ public String getErrorMessage() throws IOException {
+ return postMethod.getStatusText();
+ }
+
public void close() throws IOException {
postMethod.releaseConnection();
}
@@ -96,11 +99,6 @@ public class CommonsHttpConnection extends AbstractHttpSenderConnection {
}
protected InputStream getRawResponseInputStream() throws IOException {
- if (postMethod.getStatusCode() != HttpStatus.SC_INTERNAL_SERVER_ERROR &&
- postMethod.getStatusCode() / 100 != 2) {
- throw new HttpTransportException("Did not receive successful HTTP response: status code = " +
- postMethod.getStatusCode() + ", status message = [" + postMethod.getStatusText() + "]");
- }
return postMethod.getResponseBodyAsStream();
}
diff --git a/core/src/main/java/org/springframework/ws/transport/http/HttpServletConnection.java b/core/src/main/java/org/springframework/ws/transport/http/HttpServletConnection.java
index 1f0dfeeb..8ace983f 100644
--- a/core/src/main/java/org/springframework/ws/transport/http/HttpServletConnection.java
+++ b/core/src/main/java/org/springframework/ws/transport/http/HttpServletConnection.java
@@ -65,12 +65,20 @@ public class HttpServletConnection extends AbstractReceiverConnection implements
public void endpointNotFound() {
endpointFound = false;
- httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ getHttpServletResponse().setStatus(HttpServletResponse.SC_NOT_FOUND);
+ }
+
+ public boolean hasError() throws IOException {
+ return false;
+ }
+
+ public String getErrorMessage() throws IOException {
+ return null;
}
public void close() throws IOException {
if (!sentResponse && endpointFound) {
- httpServletResponse.setStatus(HttpServletResponse.SC_ACCEPTED);
+ getHttpServletResponse().setStatus(HttpServletResponse.SC_ACCEPTED);
}
}
@@ -79,15 +87,15 @@ public class HttpServletConnection extends AbstractReceiverConnection implements
*/
protected Iterator getRequestHeaderNames() throws IOException {
- return new EnumerationIterator(httpServletRequest.getHeaderNames());
+ return new EnumerationIterator(getHttpServletRequest().getHeaderNames());
}
protected Iterator getRequestHeaders(String name) throws IOException {
- return new EnumerationIterator(httpServletRequest.getHeaders(name));
+ return new EnumerationIterator(getHttpServletRequest().getHeaders(name));
}
protected InputStream getRequestInputStream() throws IOException {
- return httpServletRequest.getInputStream();
+ return getHttpServletRequest().getInputStream();
}
/*
@@ -95,20 +103,20 @@ public class HttpServletConnection extends AbstractReceiverConnection implements
*/
protected void addResponseHeader(String name, String value) throws IOException {
- httpServletResponse.addHeader(name, value);
+ getHttpServletResponse().addHeader(name, value);
}
protected OutputStream getResponseOutputStream() throws IOException {
- return httpServletResponse.getOutputStream();
+ return getHttpServletResponse().getOutputStream();
}
protected void onSendBeforeWrite(WebServiceMessage message) throws IOException {
sentResponse = true;
if (!message.hasFault()) {
- httpServletResponse.setStatus(HttpServletResponse.SC_OK);
+ getHttpServletResponse().setStatus(HttpServletResponse.SC_OK);
}
else {
- httpServletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ getHttpServletResponse().setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
}
diff --git a/core/src/main/java/org/springframework/ws/transport/http/HttpUrlConnection.java b/core/src/main/java/org/springframework/ws/transport/http/HttpUrlConnection.java
index 02d3bd77..439d262a 100644
--- a/core/src/main/java/org/springframework/ws/transport/http/HttpUrlConnection.java
+++ b/core/src/main/java/org/springframework/ws/transport/http/HttpUrlConnection.java
@@ -58,6 +58,10 @@ public class HttpUrlConnection extends AbstractHttpSenderConnection {
connection.disconnect();
}
+ public String getErrorMessage() throws IOException {
+ return connection.getResponseMessage();
+ }
+
/*
* Sending request
*/
@@ -113,15 +117,11 @@ public class HttpUrlConnection extends AbstractHttpSenderConnection {
}
protected InputStream getRawResponseInputStream() throws IOException {
- if (connection.getResponseCode() == HttpURLConnection.HTTP_INTERNAL_ERROR) {
+ if (connection.getResponseCode() / 100 != 2) {
return connection.getErrorStream();
}
- else if (connection.getResponseCode() / 100 == 2) {
- return connection.getInputStream();
- }
else {
- throw new HttpTransportException("Did not receive successful HTTP response: status code = " +
- connection.getResponseCode() + ", status message = [" + connection.getResponseMessage() + "]");
+ return connection.getInputStream();
}
}
}
diff --git a/core/src/main/java/org/springframework/ws/transport/http/MessageDispatcherServlet.java b/core/src/main/java/org/springframework/ws/transport/http/MessageDispatcherServlet.java
index 7e31f0e5..274ea478 100644
--- a/core/src/main/java/org/springframework/ws/transport/http/MessageDispatcherServlet.java
+++ b/core/src/main/java/org/springframework/ws/transport/http/MessageDispatcherServlet.java
@@ -25,7 +25,6 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.BeanNameAware;
-import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.servlet.DispatcherServlet;
@@ -42,24 +41,20 @@ import org.springframework.ws.wsdl.WsdlDefinition;
/**
* Servlet for simplified dispatching of Web service messages.
- *
- * This servlet is a convenient alternative to the standard Spring-MVC - * {@link DispatcherServlet} with separate - * {@link WebServiceMessageReceiverHandlerAdapter}, {@link MessageDispatcher}, and - * {@link WsdlDefinitionHandlerAdapter} instances. - * - *
This servlet automatically detects {@link EndpointAdapter EndpointAdapters}, - * {@link EndpointMapping EndpointMappings}, and - * {@link EndpointExceptionResolver EndpointExceptionResolvers} by type. - * - *
This servlet also automatically detects any {@link WsdlDefinition} in its
- * application context. This WSDL is exposed under the bean name: for example, a
- * {@link WsdlDefinition} bean named 'echo' will be exposed as
- * echo.wsdl in this servlet's context:
- * http://localhost:8080/spring-ws/echo.wsdl. When the
- * transformWsdlLocations init-param is set to true in
- * this servlet's configuration in web.xml, all location
- * attributes in the WSDL definitions will reflect the URL of the incoming request.
+ *
This servlet is a convenient alternative to the standard Spring-MVC {@link DispatcherServlet} with separate {@link + * WebServiceMessageReceiverHandlerAdapter}, {@link MessageDispatcher}, and {@link WsdlDefinitionHandlerAdapter} + * instances. + *
+ *This servlet automatically detects {@link EndpointAdapter EndpointAdapters}, {@link EndpointMapping + * EndpointMappings}, and {@link EndpointExceptionResolver EndpointExceptionResolvers} by type. + *
+ *This servlet also automatically detects any {@link WsdlDefinition} in its application context. This WSDL is
+ * exposed under the bean name: for example, a {@link WsdlDefinition} bean named 'echo' will be exposed as
+ * echo.wsdl in this servlet's context: http://localhost:8080/spring-ws/echo.wsdl. When the
+ * transformWsdlLocations init-param is set to true in this servlet's configuration in
+ * web.xml, all location attributes in the WSDL definitions will reflect the URL of the
+ * incoming request.
*
* @author Arjen Poutsma
* @see org.springframework.web.servlet.DispatcherServlet
@@ -75,8 +70,8 @@ public class MessageDispatcherServlet extends FrameworkServlet {
public static final String MESSAGE_RECEIVER_BEAN_NAME = "messageReceiver";
/**
- * Name of the class path resource (relative to the {@link MessageDispatcherServlet}
- * class) that defines MessageDispatcherServlet's default strategy names.
+ * Name of the class path resource (relative to the {@link MessageDispatcherServlet} class) that defines
+ * MessageDispatcherServlet's default strategy names.
*/
private static final String DEFAULT_STRATEGIES_PATH = "MessageDispatcherServlet.properties";
@@ -102,14 +97,13 @@ public class MessageDispatcherServlet extends FrameworkServlet {
/** Public constructor, necessary for some Web application servers. */
public MessageDispatcherServlet() {
- this.defaultStrategiesHelper = new DefaultStrategiesHelper(
+ defaultStrategiesHelper = new DefaultStrategiesHelper(
new ClassPathResource(DEFAULT_STRATEGIES_PATH, MessageDispatcherServlet.class));
}
/**
- * Sets whether relative address locations in the WSDL are to be transformed using
- * the request URI of the incoming {@link HttpServletRequest}.
- *
Defaults to false.
+ * Sets whether relative address locations in the WSDL are to be transformed using the request URI of the incoming
+ * {@link HttpServletRequest}.
Defaults to false.
*/
public void setTransformWsdlLocations(boolean transformWsdlLocations) {
this.transformWsdlLocations = transformWsdlLocations;
@@ -129,10 +123,10 @@ public class MessageDispatcherServlet extends FrameworkServlet {
protected long getLastModified(HttpServletRequest httpServletRequest) {
WsdlDefinition definition = getWsdlDefinition(httpServletRequest);
if (definition != null) {
- return this.wsdlDefinitionHandlerAdapter.getLastModified(httpServletRequest, definition);
+ return wsdlDefinitionHandlerAdapter.getLastModified(httpServletRequest, definition);
}
else {
- return this.messageReceiverHandlerAdapter.getLastModified(httpServletRequest, this.messageReceiver);
+ return messageReceiverHandlerAdapter.getLastModified(httpServletRequest, messageReceiver);
}
}
@@ -140,27 +134,27 @@ public class MessageDispatcherServlet extends FrameworkServlet {
throws Exception {
WsdlDefinition definition = getWsdlDefinition(httpServletRequest);
if (definition != null) {
- this.wsdlDefinitionHandlerAdapter.handle(httpServletRequest, httpServletResponse, definition);
+ wsdlDefinitionHandlerAdapter.handle(httpServletRequest, httpServletResponse, definition);
}
else {
- this.messageReceiverHandlerAdapter.handle(httpServletRequest, httpServletResponse, this.messageReceiver);
+ messageReceiverHandlerAdapter.handle(httpServletRequest, httpServletResponse, messageReceiver);
}
}
/**
- * Determines the {@link WsdlDefinition} for a given request, or null
- * if none is found.
+ * Determines the {@link WsdlDefinition} for a given request, or null if none is found.
*
GET,
- * whether the request uri ends with ".wsdl", and if there is a
- * WsdlDefinition with the same name as the filename in the request uri.
+ * Default implementation checks whether the request method is GET, whether the request uri ends with
+ * ".wsdl", and if there is a WsdlDefinition with the same name as the filename in the
+ * request uri.
+ *
* @param request the HttpServletRequest
* @return a definition, or null
*/
protected WsdlDefinition getWsdlDefinition(HttpServletRequest request) {
if ("GET".equals(request.getMethod()) && request.getRequestURI().endsWith(WSDL_SUFFIX_NAME)) {
String fileName = WebUtils.extractFilenameFromUrlPath(request.getRequestURI());
- return (WsdlDefinition) this.wsdlDefinitions.get(fileName);
+ return (WsdlDefinition) wsdlDefinitions.get(fileName);
}
else {
return null;
@@ -170,13 +164,13 @@ public class MessageDispatcherServlet extends FrameworkServlet {
private void initHandlerAdapters() throws BeansException {
try {
// setup the receiver adapter
- this.messageReceiverHandlerAdapter = new WebServiceMessageReceiverHandlerAdapter();
+ messageReceiverHandlerAdapter = new WebServiceMessageReceiverHandlerAdapter();
initWebServiceMessageFactory();
- this.messageReceiverHandlerAdapter.afterPropertiesSet();
+ messageReceiverHandlerAdapter.afterPropertiesSet();
// setup the wsdl adapter
- this.wsdlDefinitionHandlerAdapter = new WsdlDefinitionHandlerAdapter();
- this.wsdlDefinitionHandlerAdapter.setTransformLocations(this.transformWsdlLocations);
- this.wsdlDefinitionHandlerAdapter.afterPropertiesSet();
+ wsdlDefinitionHandlerAdapter = new WsdlDefinitionHandlerAdapter();
+ wsdlDefinitionHandlerAdapter.setTransformLocations(transformWsdlLocations);
+ wsdlDefinitionHandlerAdapter.afterPropertiesSet();
}
catch (Exception ex) {
throw new BeanInitializationException("Could not initialize handler adapters", ex);
@@ -190,43 +184,35 @@ public class MessageDispatcherServlet extends FrameworkServlet {
.getBean(WEB_SERVICE_MESSAGE_FACTORY_BEAN_NAME, WebServiceMessageFactory.class);
}
catch (NoSuchBeanDefinitionException ignored) {
- messageFactory = (WebServiceMessageFactory) this.defaultStrategiesHelper
+ messageFactory = (WebServiceMessageFactory) defaultStrategiesHelper
.getDefaultStrategy(WebServiceMessageFactory.class, getWebApplicationContext());
- if (this.logger.isInfoEnabled()) {
- this.logger.info("Unable to locate WebServiceMessageFactory with name '" +
- WEB_SERVICE_MESSAGE_FACTORY_BEAN_NAME + "': using default [" + messageFactory + "]");
- }
- if (messageFactory instanceof InitializingBean) {
- ((InitializingBean) messageFactory).afterPropertiesSet();
+ if (logger.isDebugEnabled()) {
+ logger.debug("No WebServiceMessageFactory found in servlet '" + getServletName() + "': using default");
}
}
- this.messageReceiverHandlerAdapter.setMessageFactory(messageFactory);
+ messageReceiverHandlerAdapter.setMessageFactory(messageFactory);
}
private void initMessageReceiver() {
try {
- this.messageReceiver = (WebServiceMessageReceiver) getWebApplicationContext()
+ messageReceiver = (WebServiceMessageReceiver) getWebApplicationContext()
.getBean(MESSAGE_RECEIVER_BEAN_NAME, WebServiceMessageReceiver.class);
}
catch (NoSuchBeanDefinitionException ex) {
- this.messageReceiver = (WebServiceMessageReceiver) this.defaultStrategiesHelper
+ messageReceiver = (WebServiceMessageReceiver) defaultStrategiesHelper
.getDefaultStrategy(WebServiceMessageReceiver.class, getWebApplicationContext());
- if (this.messageReceiver instanceof BeanNameAware) {
- ((BeanNameAware) this.messageReceiver).setBeanName(getServletName());
+ if (messageReceiver instanceof BeanNameAware) {
+ ((BeanNameAware) messageReceiver).setBeanName(getServletName());
}
- if (this.logger.isInfoEnabled()) {
- this.logger.info("Unable to locate MessageDispatcher with name '" + MESSAGE_RECEIVER_BEAN_NAME +
- "': using default [" + this.messageReceiver + "]");
+ if (logger.isDebugEnabled()) {
+ logger.debug("No MessageDispatcher found in servlet '" + getServletName() + "': using default");
}
}
}
- /**
- * Find all {@link WsdlDefinition WsdlDefinitions} in the ApplicationContext,
- * incuding ancestor contexts.
- */
+ /** Find all {@link WsdlDefinition WsdlDefinitions} in the ApplicationContext, incuding ancestor contexts. */
private void initWsdlDefinitions() {
- this.wsdlDefinitions = BeanFactoryUtils
+ wsdlDefinitions = BeanFactoryUtils
.beansOfTypeIncludingAncestors(getWebApplicationContext(), WsdlDefinition.class, true, false);
}
}
diff --git a/core/src/main/java/org/springframework/ws/transport/support/DefaultStrategiesHelper.java b/core/src/main/java/org/springframework/ws/transport/support/DefaultStrategiesHelper.java
index 6686ee3e..a1543aa1 100644
--- a/core/src/main/java/org/springframework/ws/transport/support/DefaultStrategiesHelper.java
+++ b/core/src/main/java/org/springframework/ws/transport/support/DefaultStrategiesHelper.java
@@ -22,20 +22,36 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
+import javax.servlet.ServletContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanClassLoaderAware;
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanInitializationException;
+import org.springframework.beans.factory.BeanNameAware;
+import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ApplicationEventPublisherAware;
+import org.springframework.context.MessageSourceAware;
+import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
+import org.springframework.web.context.ServletContextAware;
+import org.springframework.web.context.WebApplicationContext;
/**
* Helper class for for loading default implementations of an interface. Encapsulates a properties object, which
* contains strategy interface names as keys, and comma-separated class names as values.
+ *
+ * Simulates the {@link BeanFactory normal lifecycle} for beans, by calling {@link
+ * BeanFactoryAware#setBeanFactory(BeanFactory)}, {@link ApplicationContextAware#setApplicationContext(ApplicationContext)},
+ * etc.
*
* @author Arjen Poutsma
*/
@@ -68,12 +84,25 @@ public class DefaultStrategiesHelper {
}
/**
- * Create a list of strategy objects for the given strategy interface. Strategies are retrieved from the given
- * Properties object. It instantiates the strategy objects and satisifies
+ * Create a list of strategy objects for the given strategy interface. Strategies are retrieved from the
+ * Properties object given at construction-time.
+ *
+ * @param strategyInterface the strategy interface
+ * @return a list of corresponding strategy objects
+ * @throws BeansException if initialization failed
+ */
+ public List getDefaultStrategies(Class strategyInterface) throws BeanInitializationException {
+ return getDefaultStrategies(strategyInterface, null);
+ }
+
+ /**
+ * Create a list of strategy objects for the given strategy interface. Strategies are retrieved from the
+ * Properties object given at construction-time. It instantiates the strategy objects and satisifies
* ApplicationContextAware with the supplied context if necessary.
*
* @param strategyInterface the strategy interface
- * @param applicationContext used to satisfy strategies that are application context aware
+ * @param applicationContext used to satisfy strategies that are application context aware, may be
+ * null
* @return a list of corresponding strategy objects
* @throws BeansException if initialization failed
*/
@@ -88,10 +117,7 @@ public class DefaultStrategiesHelper {
result = new ArrayList(classNames.length);
for (int i = 0; i < classNames.length; i++) {
Class clazz = ClassUtils.forName(classNames[i]);
- Object strategy = BeanUtils.instantiateClass(clazz);
- if (strategy instanceof ApplicationContextAware) {
- ((ApplicationContextAware) strategy).setApplicationContext(applicationContext);
- }
+ Object strategy = instantiateBean(clazz, applicationContext);
result.add(strategy);
}
}
@@ -104,18 +130,75 @@ public class DefaultStrategiesHelper {
throw new BeanInitializationException("Could not find default strategy class for interface [" + key + "]",
ex);
}
+ }
+ /** Instantiates the given bean, simulating the standard bean lifecycle. */
+ private Object instantiateBean(Class clazz, ApplicationContext applicationContext) {
+ Object strategy = BeanUtils.instantiateClass(clazz);
+ if (strategy instanceof BeanNameAware) {
+ BeanNameAware beanNameAware = (BeanNameAware) strategy;
+ beanNameAware.setBeanName(clazz.getName());
+ }
+ if (applicationContext != null) {
+ if (strategy instanceof BeanClassLoaderAware) {
+ ((BeanClassLoaderAware) strategy).setBeanClassLoader(applicationContext.getClassLoader());
+ }
+ if (strategy instanceof BeanFactoryAware) {
+ ((BeanFactoryAware) strategy).setBeanFactory(applicationContext);
+ }
+ if (strategy instanceof ResourceLoaderAware) {
+ ((ResourceLoaderAware) strategy).setResourceLoader(applicationContext);
+ }
+ if (strategy instanceof ApplicationEventPublisherAware) {
+ ((ApplicationEventPublisherAware) strategy).setApplicationEventPublisher(applicationContext);
+ }
+ if (strategy instanceof MessageSourceAware) {
+ ((MessageSourceAware) strategy).setMessageSource(applicationContext);
+ }
+ if (strategy instanceof ApplicationContextAware) {
+ ApplicationContextAware applicationContextAware = (ApplicationContextAware) strategy;
+ applicationContextAware.setApplicationContext(applicationContext);
+ }
+ if (applicationContext instanceof WebApplicationContext && strategy instanceof ServletContextAware) {
+ ServletContext servletContext = ((WebApplicationContext) applicationContext).getServletContext();
+ ((ServletContextAware) strategy).setServletContext(servletContext);
+ }
+ }
+ if (strategy instanceof InitializingBean) {
+ InitializingBean initializingBean = (InitializingBean) strategy;
+ try {
+ initializingBean.afterPropertiesSet();
+ }
+ catch (Throwable ex) {
+ throw new BeanCreationException("Invocation of init method failed", ex);
+ }
+ }
+ return strategy;
}
/**
- * Return the default strategy object for the given strategy interface. Delegates to
- * getDefaultStrategies, expecting a single object in the list.
+ * Return the default strategy object for the given strategy interface.
*
* @param strategyInterface the strategy interface
* @return the corresponding strategy object
* @throws BeansException if initialization failed
* @see #getDefaultStrategies
*/
+ public Object getDefaultStrategy(Class strategyInterface) throws BeanInitializationException {
+ return getDefaultStrategy(strategyInterface, null);
+ }
+
+ /**
+ * Return the default strategy object for the given strategy interface.
+ *
null
+ * @return the corresponding strategy object
+ * @throws BeansException if initialization failed
+ */
public Object getDefaultStrategy(Class strategyInterface, ApplicationContext applicationContext)
throws BeanInitializationException {
List result = getDefaultStrategies(strategyInterface, applicationContext);
diff --git a/core/src/main/java/org/springframework/ws/transport/support/WebServiceMessageReceiverObjectSupport.java b/core/src/main/java/org/springframework/ws/transport/support/WebServiceMessageReceiverObjectSupport.java
index fa5f040c..63c3a7a7 100644
--- a/core/src/main/java/org/springframework/ws/transport/support/WebServiceMessageReceiverObjectSupport.java
+++ b/core/src/main/java/org/springframework/ws/transport/support/WebServiceMessageReceiverObjectSupport.java
@@ -60,7 +60,6 @@ public abstract class WebServiceMessageReceiverObjectSupport implements Initiali
public void afterPropertiesSet() throws Exception {
Assert.notNull(messageFactory, "messageFactory is required");
- logger.info("Using message factory [" + messageFactory + "]");
}
/**
diff --git a/core/src/main/resources/org/springframework/ws/client/core/WebServiceTemplate.properties b/core/src/main/resources/org/springframework/ws/client/core/WebServiceTemplate.properties
index 539831b6..2078d301 100644
--- a/core/src/main/resources/org/springframework/ws/client/core/WebServiceTemplate.properties
+++ b/core/src/main/resources/org/springframework/ws/client/core/WebServiceTemplate.properties
@@ -1,5 +1,5 @@
# Default implementation classes for WebServiceTemplate's strategy interfaces.
# Not meant to be customized by application developers.
-
+org.springframework.ws.client.core.FaultMessageResolver=org.springframework.ws.soap.client.core.SoapFaultMessageResolver
org.springframework.ws.WebServiceMessageFactory=org.springframework.ws.soap.saaj.SaajSoapMessageFactory
org.springframework.ws.transport.WebServiceMessageSender=org.springframework.ws.transport.http.HttpUrlConnectionMessageSender
\ No newline at end of file
diff --git a/core/src/test/java/org/springframework/ws/client/core/SimpleFaultResolverTest.java b/core/src/test/java/org/springframework/ws/client/core/SimpleFaultMessageResolverTest.java
similarity index 90%
rename from core/src/test/java/org/springframework/ws/client/core/SimpleFaultResolverTest.java
rename to core/src/test/java/org/springframework/ws/client/core/SimpleFaultMessageResolverTest.java
index 72fb4c31..822a0fd3 100644
--- a/core/src/test/java/org/springframework/ws/client/core/SimpleFaultResolverTest.java
+++ b/core/src/test/java/org/springframework/ws/client/core/SimpleFaultMessageResolverTest.java
@@ -21,12 +21,12 @@ import org.easymock.MockControl;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.client.WebServiceFaultException;
-public class SimpleFaultResolverTest extends TestCase {
+public class SimpleFaultMessageResolverTest extends TestCase {
- private SimpleFaultResolver resolver;
+ private SimpleFaultMessageResolver resolver;
protected void setUp() throws Exception {
- resolver = new SimpleFaultResolver();
+ resolver = new SimpleFaultMessageResolver();
}
public void testResolveFault() throws Exception {
diff --git a/core/src/test/java/org/springframework/ws/client/core/SimpleSaajServlet.java b/core/src/test/java/org/springframework/ws/client/core/SimpleSaajServlet.java
index 13bd7f77..103af9e4 100644
--- a/core/src/test/java/org/springframework/ws/client/core/SimpleSaajServlet.java
+++ b/core/src/test/java/org/springframework/ws/client/core/SimpleSaajServlet.java
@@ -31,6 +31,8 @@ import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
+import org.springframework.util.StringUtils;
+
/**
* A simple Servlet that uses SAAJ to echo request.
*
@@ -53,52 +55,32 @@ public class SimpleSaajServlet extends HttpServlet {
private MimeHeaders getHeaders(HttpServletRequest httpServletRequest) {
Enumeration enumeration = httpServletRequest.getHeaderNames();
MimeHeaders headers = new MimeHeaders();
-
while (enumeration.hasMoreElements()) {
String headerName = (String) enumeration.nextElement();
String headerValue = httpServletRequest.getHeader(headerName);
-
StringTokenizer values = new StringTokenizer(headerValue, ",");
-
while (values.hasMoreTokens()) {
headers.addHeader(headerName, values.nextToken().trim());
}
}
-
return headers;
}
private void putHeaders(MimeHeaders headers, HttpServletResponse res) {
Iterator it = headers.getAllHeaders();
-
while (it.hasNext()) {
MimeHeader header = (MimeHeader) it.next();
-
String[] values = headers.getHeader(header.getName());
-
- if (values.length == 1) {
- res.setHeader(header.getName(), header.getValue());
- }
- else {
- StringBuffer concat = new StringBuffer();
- int i = 0;
-
- while (i < values.length) {
- if (i != 0) {
- concat.append(',');
- }
- concat.append(values[i++]);
- }
- res.setHeader(header.getName(), concat.toString());
- }
+ String value = StringUtils.arrayToCommaDelimitedString(values);
+ res.setHeader(header.getName(), value);
}
}
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
MimeHeaders headers = getHeaders(req);
- SOAPMessage msg = msgFactory.createMessage(headers, req.getInputStream());
- SOAPMessage reply = onMessage(msg);
+ SOAPMessage request = msgFactory.createMessage(headers, req.getInputStream());
+ SOAPMessage reply = onMessage(request);
if (reply != null) {
if (reply.saveRequired()) {
reply.saveChanges();
@@ -117,7 +99,7 @@ public class SimpleSaajServlet extends HttpServlet {
}
}
- public SOAPMessage onMessage(SOAPMessage message) {
+ protected SOAPMessage onMessage(SOAPMessage message) {
return message;
}
diff --git a/core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateIntegrationTest.java b/core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateIntegrationTest.java
index 09d16df4..b6ad6519 100644
--- a/core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateIntegrationTest.java
+++ b/core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateIntegrationTest.java
@@ -16,16 +16,47 @@
package org.springframework.ws.client.core;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.MessageFactory;
+import javax.xml.soap.MimeHeader;
+import javax.xml.soap.MimeHeaders;
+import javax.xml.soap.SOAPBody;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
import org.custommonkey.xmlunit.XMLTestCase;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.Context;
+import org.mortbay.jetty.servlet.ServletHolder;
+import org.springframework.util.StringUtils;
+import org.springframework.ws.client.WebServiceTransportException;
+import org.springframework.ws.pox.dom.DomPoxMessageFactory;
+import org.springframework.ws.soap.SoapMessageFactory;
import org.springframework.ws.soap.axiom.AxiomSoapMessageFactory;
+import org.springframework.ws.soap.client.SoapFaultClientException;
+import org.springframework.ws.soap.client.core.SoapFaultMessageResolver;
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
-import org.springframework.ws.transport.http.HttpUrlConnectionMessageSender;
+import org.springframework.ws.transport.http.CommonsHttpMessageSender;
import org.springframework.xml.transform.StringResult;
import org.springframework.xml.transform.StringSource;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
public class WebServiceTemplateIntegrationTest extends XMLTestCase {
@@ -36,31 +67,207 @@ public class WebServiceTemplateIntegrationTest extends XMLTestCase {
protected void setUp() throws Exception {
jettyServer = new Server(8888);
Context jettyContext = new Context(jettyServer, "/");
- jettyContext.addServlet(SimpleSaajServlet.class, "/");
+ jettyContext.addServlet(new ServletHolder(new EchoSoapServlet()), "/soap/echo");
+ jettyContext.addServlet(new ServletHolder(new SoapFaultServlet()), "/soap/fault");
+ jettyContext.addServlet(new ServletHolder(new NoResponseSoapServlet()), "/soap/noResponse");
+ jettyContext.addServlet(new ServletHolder(new PoxServlet()), "/pox");
+ jettyContext.addServlet(new ServletHolder(new ErrorServlet(404)), "/errors/notfound");
+ jettyContext.addServlet(new ServletHolder(new ErrorServlet(500)), "/errors/server");
jettyServer.start();
template = new WebServiceTemplate();
- template.setDefaultUri("http://localhost:8888/");
- template.setMessageSender(new HttpUrlConnectionMessageSender());
+ template.setMessageSender(new CommonsHttpMessageSender());
+ template.setFaultMessageResolver(new SoapFaultMessageResolver());
}
protected void tearDown() throws Exception {
jettyServer.stop();
}
- public void testSendAndReceiveSaaj() throws Exception {
- template.setMessageFactory(new SaajSoapMessageFactory(MessageFactory.newInstance()));
- String content = "