diff --git a/core/src/main/java/org/springframework/ws/client/core/FaultMessageResolver.java b/core/src/main/java/org/springframework/ws/client/core/FaultMessageResolver.java
index 1fa5b0ec..b6f2e6b0 100644
--- a/core/src/main/java/org/springframework/ws/client/core/FaultMessageResolver.java
+++ b/core/src/main/java/org/springframework/ws/client/core/FaultMessageResolver.java
@@ -21,7 +21,7 @@ import java.io.IOException;
import org.springframework.ws.WebServiceMessage;
/**
- * Defines the interface for objects than can resolve fault {@link WebServiceMessage}.
+ * Defines the interface for objects than can resolve fault {@link WebServiceMessage}s.
*
* @author Arjen Poutsma
* @since 1.0.0
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 ccd6e1cc..5fb557c9 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
@@ -121,6 +121,8 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
private String defaultUri;
+ private boolean checkConnectionForError = true;
+
private boolean checkConnectionForFault = true;
private ClientInterceptor[] interceptors;
@@ -194,11 +196,30 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
}
/**
- * Indicates whether the {@link FaultAwareWebServiceConnection#hasFault() connection} should be checked for fault
- * indicators (true), or whether we should rely on the {@link FaultAwareWebServiceMessage#hasFault()
- * message} only (false). The default is true.
+ * Indicates whether the {@linkplain WebServiceConnection#hasError() connection} should be checked for error
+ * indicators (true), or whether these should be ignored (false). The default is
+ * true.
*
false
+ * allows this template to deal with non-conformant services.
+ *
+ * @see #hasError(WebServiceConnection, WebServiceMessage)
+ * @see SOAP 1.1 specification
+ * @see WS-I Basic
+ * Profile
+ */
+ public void setCheckConnectionForError(boolean checkConnectionForError) {
+ this.checkConnectionForError = checkConnectionForError;
+ }
+
+ /**
+ * Indicates whether the {@linkplain FaultAwareWebServiceConnection#hasFault() connection} should be checked for
+ * fault indicators (true), or whether we should rely on the {@link
+ * FaultAwareWebServiceMessage#hasFault() message} only (false). The default is true.
+ *
+ * When using an HTTP transport, this property defines whether to check the HTTP response status code for fault
* indicators. Both the SOAP specification and the WS-I Basic Profile define that a Web service must return a "500
* Internal Server Error" HTTP status code if the response envelope is a Fault. Setting this property to
* false allows this template to deal with non-conformant services.
@@ -540,8 +561,9 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
* @throws IOException in case of I/O errors
*/
protected boolean hasError(WebServiceConnection connection, WebServiceMessage request) throws IOException {
- if (connection.hasError() && checkConnectionForFault) {
- if (connection instanceof FaultAwareWebServiceConnection) {
+ if (checkConnectionForError && connection.hasError()) {
+ // could be a fault
+ if (checkConnectionForFault && connection instanceof FaultAwareWebServiceConnection) {
FaultAwareWebServiceConnection faultConnection = (FaultAwareWebServiceConnection) connection;
return !(faultConnection.hasFault() && request instanceof FaultAwareWebServiceMessage);
}
@@ -562,6 +584,9 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
* WebServiceMessageExtractor)}, if any
*/
protected Object handleError(WebServiceConnection connection, WebServiceMessage request) throws IOException {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Received error for request [" + request + "]");
+ }
throw new WebServiceTransportException(connection.getErrorMessage());
}
@@ -667,8 +692,10 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
* WebServiceMessageExtractor)}, if any
*/
protected Object handleFault(WebServiceConnection connection, MessageContext messageContext) throws IOException {
- if (getFaultMessageResolver() != null) {
+ if (logger.isDebugEnabled()) {
logger.debug("Received Fault message for request [" + messageContext.getRequest() + "]");
+ }
+ if (getFaultMessageResolver() != null) {
getFaultMessageResolver().resolveFault(messageContext.getResponse());
return null;
}
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 b33c5665..9df2a86f 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
@@ -79,7 +79,7 @@ public abstract class AbstractHttpSenderConnection extends AbstractSenderConnect
return isGzipResponse() ? new GZIPInputStream(inputStream) : inputStream;
}
- /** Determine whether the given response is a GZIP response. */
+ /** Determine whether the response is a GZIP response. */
private boolean isGzipResponse() throws IOException {
Iterator iterator = getResponseHeaders(HttpTransportConstants.HEADER_CONTENT_ENCODING);
if (iterator.hasNext()) {
@@ -106,7 +106,17 @@ public abstract class AbstractHttpSenderConnection extends AbstractSenderConnect
*/
public final boolean hasFault() throws IOException {
- return HttpTransportConstants.STATUS_INTERNAL_SERVER_ERROR == getResponseCode();
+ return HttpTransportConstants.STATUS_INTERNAL_SERVER_ERROR == getResponseCode() && isXmlResponse();
+ }
+
+ /** Determine whether the response is a XML message. */
+ private boolean isXmlResponse() throws IOException {
+ Iterator iterator = getResponseHeaders(HttpTransportConstants.HEADER_CONTENT_TYPE);
+ if (iterator.hasNext()) {
+ String contentType = ((String) iterator.next()).toLowerCase();
+ return contentType.indexOf("xml") != -1;
+ }
+ return false;
}
public final void setFault(boolean fault) {
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 43fe38b2..c96368a8 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
@@ -132,6 +132,7 @@ public class WebServiceTemplateIntegrationTest extends XMLTestCase {
//expected
}
template.setCheckConnectionForFault(false);
+ template.setCheckConnectionForError(false);
try {
template.sendSourceAndReceiveToResult("http://localhost:8888/soap/badRequestFault",
new StringSource(content), result);
diff --git a/core/src/test/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSenderIntegrationTestCase.java b/core/src/test/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSenderIntegrationTestCase.java
index 5bf0a7dc..4bb4f2d9 100644
--- a/core/src/test/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSenderIntegrationTestCase.java
+++ b/core/src/test/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSenderIntegrationTestCase.java
@@ -35,6 +35,12 @@ import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
+import org.custommonkey.xmlunit.XMLTestCase;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.servlet.Context;
+import org.mortbay.jetty.servlet.ServletHolder;
+
import org.springframework.util.FileCopyUtils;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
@@ -45,12 +51,6 @@ import org.springframework.ws.transport.WebServiceConnection;
import org.springframework.xml.transform.StringResult;
import org.springframework.xml.transform.StringSource;
-import org.custommonkey.xmlunit.XMLTestCase;
-import org.custommonkey.xmlunit.XMLUnit;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.servlet.Context;
-import org.mortbay.jetty.servlet.ServletHolder;
-
public abstract class AbstractHttpWebServiceMessageSenderIntegrationTestCase extends XMLTestCase {
private Server jettyServer;
@@ -146,6 +146,7 @@ public abstract class AbstractHttpWebServiceMessageSenderIntegrationTestCase ext
public void testSendAndReceiveFault() throws Exception {
MyServlet servlet = new MyServlet();
servlet.setResponseStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ servlet.setResponse(true);
jettyContext.addServlet(new ServletHolder(servlet), "/");
jettyServer.start();
FaultAwareWebServiceConnection connection =