diff --git a/spring-ws-core/src/main/java/org/springframework/ws/FaultAwareWebServiceMessage.java b/spring-ws-core/src/main/java/org/springframework/ws/FaultAwareWebServiceMessage.java
index 087abc15..77911b90 100644
--- a/spring-ws-core/src/main/java/org/springframework/ws/FaultAwareWebServiceMessage.java
+++ b/spring-ws-core/src/main/java/org/springframework/ws/FaultAwareWebServiceMessage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2010 the original author or authors.
+ * Copyright 2005-2014 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.
@@ -16,6 +16,8 @@
package org.springframework.ws;
+import javax.xml.namespace.QName;
+
/**
* Sub-interface of {@link WebServiceMessage} that can contain special Fault messages. Fault messages (such as {@link
* org.springframework.ws.soap.SoapFault} SOAP Faults) often require different processing rules.
@@ -34,6 +36,12 @@ public interface FaultAwareWebServiceMessage extends WebServiceMessage {
*/
boolean hasFault();
+ /**
+ * Returns the fault code, if any.
+ */
+ QName getFaultCode();
+
+
/**
* Returns the fault reason message.
*
diff --git a/spring-ws-core/src/main/java/org/springframework/ws/soap/AbstractSoapMessage.java b/spring-ws-core/src/main/java/org/springframework/ws/soap/AbstractSoapMessage.java
index 0213098d..c070cce0 100644
--- a/spring-ws-core/src/main/java/org/springframework/ws/soap/AbstractSoapMessage.java
+++ b/spring-ws-core/src/main/java/org/springframework/ws/soap/AbstractSoapMessage.java
@@ -16,6 +16,7 @@
package org.springframework.ws.soap;
+import javax.xml.namespace.QName;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
@@ -61,7 +62,17 @@ public abstract class AbstractSoapMessage extends AbstractMimeMessage implements
return getSoapBody().hasFault();
}
- /** Returns {@code getSoapBody().getFault().getFaultStringOrReason()}. */
+ /** Returns {@code getSoapBody().getFault().getFaultCode()}. */
+ @Override
+ public final QName getFaultCode() {
+ if (hasFault()) {
+ return getSoapBody().getFault().getFaultCode();
+ } else {
+ return null;
+ }
+ }
+
+ /** Returns {@code getSoapBody().getFault().getFaultStringOrReason()}. */
@Override
public final String getFaultReason() {
if (hasFault()) {
diff --git a/spring-ws-core/src/main/java/org/springframework/ws/transport/FaultAwareWebServiceConnection.java b/spring-ws-core/src/main/java/org/springframework/ws/transport/FaultAwareWebServiceConnection.java
index fe7cd28b..b83546d1 100644
--- a/spring-ws-core/src/main/java/org/springframework/ws/transport/FaultAwareWebServiceConnection.java
+++ b/spring-ws-core/src/main/java/org/springframework/ws/transport/FaultAwareWebServiceConnection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2014 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.
@@ -17,6 +17,7 @@
package org.springframework.ws.transport;
import java.io.IOException;
+import javax.xml.namespace.QName;
import org.springframework.ws.soap.SoapFault;
@@ -47,6 +48,18 @@ public interface FaultAwareWebServiceConnection extends WebServiceConnection {
*
* @param fault {@code true} if this will send a fault; {@code false} otherwise.
* @throws IOException in case of I/O errors
+ * @deprecated In favor of {@link #setFaultCode(QName)}
*/
+ @Deprecated
void setFault(boolean fault) throws IOException;
+
+ /**
+ * Sets a specific fault code.
+ *
+ *
Typically implemented by setting an HTTP status code.
+ *
+ * @param faultCode the fault code to be set on the connection, or {@code null} for no fault.
+ * @throws IOException in case of I/O errors
+ */
+ void setFaultCode(QName faultCode) throws IOException;
}
diff --git a/spring-ws-core/src/main/java/org/springframework/ws/transport/http/AbstractHttpSenderConnection.java b/spring-ws-core/src/main/java/org/springframework/ws/transport/http/AbstractHttpSenderConnection.java
index e783aa32..83ebb19c 100644
--- a/spring-ws-core/src/main/java/org/springframework/ws/transport/http/AbstractHttpSenderConnection.java
+++ b/spring-ws-core/src/main/java/org/springframework/ws/transport/http/AbstractHttpSenderConnection.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.zip.GZIPInputStream;
+import javax.xml.namespace.QName;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;
@@ -119,15 +120,34 @@ public abstract class AbstractHttpSenderConnection extends AbstractSenderConnect
@Override
public final boolean hasFault() throws IOException {
- return HttpTransportConstants.STATUS_INTERNAL_SERVER_ERROR == getResponseCode() && isXmlResponse();
+ // SOAP 1.1 specifies a 500 status code for faults
+ // SOAP 1.2 specifies a 400 status code for sender faults, and 500 for all other faults
+ switch (getResponseCode()) {
+ case HttpTransportConstants.STATUS_INTERNAL_SERVER_ERROR:
+ return isSoap11Response() || isSoap12Response();
+ case HttpTransportConstants.STATUS_BAD_REQUEST:
+ return isSoap12Response();
+ default:
+ return false;
+ }
}
- /** Determine whether the response is a XML message. */
- private boolean isXmlResponse() throws IOException {
+ /** Determine whether the response is a SOAP 1.1 message. */
+ private boolean isSoap11Response() throws IOException {
Iterator iterator = getResponseHeaders(HttpTransportConstants.HEADER_CONTENT_TYPE);
if (iterator.hasNext()) {
String contentType = iterator.next().toLowerCase();
- return contentType.contains("xml");
+ return contentType.contains("text/xml");
+ }
+ return false;
+ }
+
+ /** Determine whether the response is a SOAP 1.1 message. */
+ private boolean isSoap12Response() throws IOException {
+ Iterator iterator = getResponseHeaders(HttpTransportConstants.HEADER_CONTENT_TYPE);
+ if (iterator.hasNext()) {
+ String contentType = iterator.next().toLowerCase();
+ return contentType.contains("application/soap+xml");
}
return false;
}
@@ -136,4 +156,7 @@ public abstract class AbstractHttpSenderConnection extends AbstractSenderConnect
public final void setFault(boolean fault) {
}
+ @Override
+ public final void setFaultCode(QName faultCode) throws IOException {
+ }
}
diff --git a/spring-ws-core/src/main/java/org/springframework/ws/transport/http/HttpServletConnection.java b/spring-ws-core/src/main/java/org/springframework/ws/transport/http/HttpServletConnection.java
index 00d2a66c..d735133a 100644
--- a/spring-ws-core/src/main/java/org/springframework/ws/transport/http/HttpServletConnection.java
+++ b/spring-ws-core/src/main/java/org/springframework/ws/transport/http/HttpServletConnection.java
@@ -24,6 +24,8 @@ import java.net.URISyntaxException;
import java.util.Iterator;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPConstants;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.transport.AbstractReceiverConnection;
@@ -163,4 +165,22 @@ public class HttpServletConnection extends AbstractReceiverConnection
}
statusCodeSet = true;
}
+
+ @Override
+ public void setFaultCode(QName faultCode) throws IOException {
+ if (faultCode != null) {
+ if (SOAPConstants.SOAP_SENDER_FAULT.equals(faultCode)) {
+ getHttpServletResponse()
+ .setStatus(HttpTransportConstants.STATUS_BAD_REQUEST);
+ }
+ else {
+ getHttpServletResponse()
+ .setStatus(HttpTransportConstants.STATUS_INTERNAL_SERVER_ERROR);
+ }
+ }
+ else {
+ getHttpServletResponse().setStatus(HttpTransportConstants.STATUS_OK);
+ }
+ statusCodeSet = true;
+ }
}
diff --git a/spring-ws-core/src/main/java/org/springframework/ws/transport/http/HttpTransportConstants.java b/spring-ws-core/src/main/java/org/springframework/ws/transport/http/HttpTransportConstants.java
index ba3558ac..22edf8d5 100644
--- a/spring-ws-core/src/main/java/org/springframework/ws/transport/http/HttpTransportConstants.java
+++ b/spring-ws-core/src/main/java/org/springframework/ws/transport/http/HttpTransportConstants.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2014 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.
@@ -44,6 +44,9 @@ public interface HttpTransportConstants extends TransportConstants {
/** The "204 No Content" status code. */
int STATUS_NO_CONTENT = 204;
+ /** The "400 Bad Request" status code. */
+ int STATUS_BAD_REQUEST = 400;
+
/** The "404 Not Found" status code. */
int STATUS_NOT_FOUND = 404;
diff --git a/spring-ws-core/src/main/java/org/springframework/ws/transport/support/WebServiceMessageReceiverObjectSupport.java b/spring-ws-core/src/main/java/org/springframework/ws/transport/support/WebServiceMessageReceiverObjectSupport.java
index f93ea9a0..31471cd5 100644
--- a/spring-ws-core/src/main/java/org/springframework/ws/transport/support/WebServiceMessageReceiverObjectSupport.java
+++ b/spring-ws-core/src/main/java/org/springframework/ws/transport/support/WebServiceMessageReceiverObjectSupport.java
@@ -93,7 +93,7 @@ public abstract class WebServiceMessageReceiverObjectSupport implements Initiali
connection instanceof FaultAwareWebServiceConnection) {
FaultAwareWebServiceMessage faultResponse = (FaultAwareWebServiceMessage) response;
FaultAwareWebServiceConnection faultConnection = (FaultAwareWebServiceConnection) connection;
- faultConnection.setFault(faultResponse.hasFault());
+ faultConnection.setFaultCode(faultResponse.getFaultCode());
}
connection.send(messageContext.getResponse());
}
diff --git a/spring-ws-core/src/test/java/org/springframework/ws/MockWebServiceMessage.java b/spring-ws-core/src/test/java/org/springframework/ws/MockWebServiceMessage.java
index db0de58c..fc37d1a4 100644
--- a/spring-ws-core/src/test/java/org/springframework/ws/MockWebServiceMessage.java
+++ b/spring-ws-core/src/test/java/org/springframework/ws/MockWebServiceMessage.java
@@ -23,6 +23,7 @@ import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
+import javax.xml.namespace.QName;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
@@ -49,9 +50,11 @@ public class MockWebServiceMessage implements FaultAwareWebServiceMessage {
private boolean fault = false;
+ private QName faultCode;
+
private String faultReason;
- public MockWebServiceMessage() {
+ public MockWebServiceMessage() {
}
public MockWebServiceMessage(Source source) throws TransformerException {
@@ -126,7 +129,16 @@ public class MockWebServiceMessage implements FaultAwareWebServiceMessage {
this.fault = fault;
}
- @Override
+ @Override
+ public QName getFaultCode() {
+ return faultCode;
+ }
+
+ public void setFaultCode(QName faultCode) {
+ this.faultCode = faultCode;
+ }
+
+ @Override
public String getFaultReason() {
return faultReason;
}
diff --git a/spring-ws-core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateIntegrationTest.java b/spring-ws-core/src/test/java/org/springframework/ws/client/core/AbstractSoap11WebServiceTemplateIntegrationTestCase.java
similarity index 71%
rename from spring-ws-core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateIntegrationTest.java
rename to spring-ws-core/src/test/java/org/springframework/ws/client/core/AbstractSoap11WebServiceTemplateIntegrationTestCase.java
index 873f3a20..0e97531b 100644
--- a/spring-ws-core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateIntegrationTest.java
+++ b/spring-ws-core/src/test/java/org/springframework/ws/client/core/AbstractSoap11WebServiceTemplateIntegrationTestCase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2010 the original author or authors.
+ * Copyright 2005-2014 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.
@@ -20,9 +20,7 @@ import java.io.IOException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.StringTokenizer;
-import javax.activation.CommandMap;
import javax.activation.DataHandler;
-import javax.activation.MailcapCommandMap;
import javax.mail.util.ByteArrayDataSource;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
@@ -30,8 +28,6 @@ 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.soap.MessageFactory;
import javax.xml.soap.MimeHeader;
import javax.xml.soap.MimeHeaders;
@@ -44,8 +40,18 @@ import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import static org.junit.Assert.assertEquals;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.servlet.Context;
+import org.mortbay.jetty.servlet.ServletHolder;
+import org.xml.sax.SAXException;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;
@@ -53,32 +59,15 @@ import org.springframework.oxm.XmlMappingException;
import org.springframework.util.StringUtils;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.client.WebServiceTransportException;
-import org.springframework.ws.pox.dom.DomPoxMessageFactory;
import org.springframework.ws.soap.SoapMessage;
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.saaj.SaajSoapMessageFactory;
-import org.springframework.ws.transport.http.CommonsHttpMessageSender;
+import org.springframework.ws.transport.http.HttpComponentsMessageSender;
import org.springframework.ws.transport.support.FreePortScanner;
import org.springframework.xml.transform.StringResult;
import org.springframework.xml.transform.StringSource;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.servlet.Context;
-import org.mortbay.jetty.servlet.ServletHolder;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
-import static org.junit.Assert.assertEquals;
-
-public class WebServiceTemplateIntegrationTest {
+public abstract class AbstractSoap11WebServiceTemplateIntegrationTestCase {
private static Server jettyServer;
@@ -102,88 +91,29 @@ public class WebServiceTemplateIntegrationTest {
jettyContext.addServlet(new ServletHolder(badRequestFault), "/soap/badRequestFault");
jettyContext.addServlet(new ServletHolder(new NoResponseSoapServlet()), "/soap/noResponse");
jettyContext.addServlet(new ServletHolder(new AttachmentsServlet()), "/soap/attachment");
- 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();
}
-
- /**
- * A workaround for the faulty XmlDataContentHandler in the SAAJ RI, which cannot handle mime types such as
- * "text/xml; charset=UTF-8", causing issues with Axiom. We basically reset the command map
- */
- @Before
- public void removeXmlDataContentHandler() throws SOAPException {
- MessageFactory messageFactory = MessageFactory.newInstance();
- SOAPMessage message = messageFactory.createMessage();
- message.createAttachmentPart();
- CommandMap.setDefaultCommandMap(new MailcapCommandMap());
- }
-
- @AfterClass
- public static void stopJetty() throws Exception {
- if (jettyServer.isRunning()) {
- jettyServer.stop();
- }
- }
-
- @Test
- public void testSaaj() throws Exception {
- doSoap(new SaajSoapMessageFactory(MessageFactory.newInstance()));
- }
- @Test
- public void testAxiom() throws Exception {
- doSoap(new AxiomSoapMessageFactory());
- }
+ @AfterClass
+ public static void stopJetty() throws Exception {
+ if (jettyServer.isRunning()) {
+ jettyServer.stop();
+ }
+ }
- @Test
- public void testAxiomNonCaching() throws Exception {
- AxiomSoapMessageFactory axiomFactory = new AxiomSoapMessageFactory();
- axiomFactory.setPayloadCaching(false);
- doSoap(axiomFactory);
- }
+ @Before
+ public void createWebServiceTemplate() throws Exception {
+ template = new WebServiceTemplate(createMessageFactory());
+ template.setMessageSender(new HttpComponentsMessageSender());
+ }
- @Test
- public void testPox() throws Exception {
- template = new WebServiceTemplate(new DomPoxMessageFactory());
- template.setMessageSender(new CommonsHttpMessageSender());
- String content = "";
- StringResult result = new StringResult();
- template.sendSourceAndReceiveToResult(baseUrl + "/pox", new StringSource(content), result);
- assertXMLEqual(content, result.toString());
- try {
- template.sendSourceAndReceiveToResult(baseUrl + "/errors/notfound", new StringSource(content),
- new StringResult());
- Assert.fail("WebServiceTransportException expected");
- }
- catch (WebServiceTransportException ex) {
- //expected
- }
- try {
- template.sendSourceAndReceiveToResult(baseUrl + "/errors/server", new StringSource(content),
- result);
- Assert.fail("WebServiceTransportException expected");
- }
- catch (WebServiceTransportException ex) {
- //expected
- }
- }
- private void doSoap(SoapMessageFactory messageFactory) throws Exception {
- template = new WebServiceTemplate(messageFactory);
- template.setMessageSender(new CommonsHttpMessageSender());
- sendSourceAndReceiveToResult();
- sendSourceAndReceiveToResultNoResponse();
- marshalSendAndReceiveResponse();
- marshalSendAndReceiveNoResponse();
- notFound();
- fault();
- faultNonCompliant();
- attachment();
- }
+ public abstract SoapMessageFactory createMessageFactory() throws Exception;
- private void sendSourceAndReceiveToResult() throws SAXException, IOException {
+ @Test
+ public void sendSourceAndReceiveToResult() throws SAXException, IOException {
StringResult result = new StringResult();
boolean b = template.sendSourceAndReceiveToResult(baseUrl + "/soap/echo",
new StringSource(messagePayload), result);
@@ -191,17 +121,20 @@ public class WebServiceTemplateIntegrationTest {
assertXMLEqual(messagePayload, result.toString());
}
- private void sendSourceAndReceiveToResultNoResponse() {
+ @Test
+ public void sendSourceAndReceiveToResultNoResponse() {
boolean b = template.sendSourceAndReceiveToResult(baseUrl + "/soap/noResponse",
new StringSource(messagePayload), new StringResult());
Assert.assertFalse("Invalid result", b);
}
- private void marshalSendAndReceiveResponse() throws TransformerConfigurationException {
+ @Test
+ public void marshalSendAndReceiveResponse() throws TransformerConfigurationException {
final Transformer transformer = TransformerFactory.newInstance().newTransformer();
final Object requestObject = new Object();
Marshaller marshaller = new Marshaller() {
+ @Override
public void marshal(Object graph, Result result) throws XmlMappingException, IOException {
Assert.assertEquals("Invalid object", graph, requestObject);
try {
@@ -212,6 +145,7 @@ public class WebServiceTemplateIntegrationTest {
}
}
+ @Override
public boolean supports(Class> clazz) {
Assert.assertEquals("Invalid class", Object.class, clazz);
return true;
@@ -220,10 +154,12 @@ public class WebServiceTemplateIntegrationTest {
final Object responseObject = new Object();
Unmarshaller unmarshaller = new Unmarshaller() {
+ @Override
public Object unmarshal(Source source) throws XmlMappingException, IOException {
return responseObject;
}
+ @Override
public boolean supports(Class> clazz) {
Assert.assertEquals("Invalid class", Object.class, clazz);
return true;
@@ -235,11 +171,13 @@ public class WebServiceTemplateIntegrationTest {
Assert.assertEquals("Invalid response object", responseObject, result);
}
- private void marshalSendAndReceiveNoResponse() throws TransformerConfigurationException {
+ @Test
+ public void marshalSendAndReceiveNoResponse() throws TransformerConfigurationException {
final Transformer transformer = TransformerFactory.newInstance().newTransformer();
final Object requestObject = new Object();
Marshaller marshaller = new Marshaller() {
+ @Override
public void marshal(Object graph, Result result) throws XmlMappingException, IOException {
Assert.assertEquals("Invalid object", graph, requestObject);
try {
@@ -250,6 +188,7 @@ public class WebServiceTemplateIntegrationTest {
}
}
+ @Override
public boolean supports(Class> clazz) {
Assert.assertEquals("Invalid class", Object.class, clazz);
return true;
@@ -260,7 +199,8 @@ public class WebServiceTemplateIntegrationTest {
Assert.assertNull("Invalid response object", result);
}
- private void notFound() {
+ @Test
+ public void notFound() {
try {
template.sendSourceAndReceiveToResult(baseUrl + "/errors/notfound",
new StringSource(messagePayload), new StringResult());
@@ -271,7 +211,8 @@ public class WebServiceTemplateIntegrationTest {
}
}
- private void fault() {
+ @Test
+ public void fault() {
Result result = new StringResult();
try {
template.sendSourceAndReceiveToResult(baseUrl + "/soap/fault", new StringSource(messagePayload),
@@ -283,7 +224,8 @@ public class WebServiceTemplateIntegrationTest {
}
}
- private void faultNonCompliant() {
+ @Test
+ public void faultNonCompliant() {
Result result = new StringResult();
template.setCheckConnectionForFault(false);
template.setCheckConnectionForError(false);
@@ -297,10 +239,12 @@ public class WebServiceTemplateIntegrationTest {
}
}
- private void attachment() {
+ @Test
+ public void attachment() {
template.sendSourceAndReceiveToResult(baseUrl + "/soap/attachment", new StringSource(messagePayload),
new WebServiceMessageCallback() {
+ @Override
public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
SoapMessage soapMessage = (SoapMessage) message;
final String attachmentContent = "content";
@@ -325,36 +269,7 @@ public class WebServiceTemplateIntegrationTest {
}
}
- /** Simple POX Servlet. */
- private static class PoxServlet extends HttpServlet {
-
- private DocumentBuilderFactory documentBuilderFactory;
-
- private TransformerFactory transformerFactory;
-
- @Override
- public void init(ServletConfig servletConfig) throws ServletException {
- super.init(servletConfig);
- documentBuilderFactory = DocumentBuilderFactory.newInstance();
- documentBuilderFactory.setNamespaceAware(true);
- transformerFactory = TransformerFactory.newInstance();
- }
-
- @Override
- public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- try {
- DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
- Document message = documentBuilder.parse(req.getInputStream());
- Transformer transformer = transformerFactory.newTransformer();
- transformer.transform(new DOMSource(message), new StreamResult(resp.getOutputStream()));
- }
- catch (Exception ex) {
- throw new ServletException("POX POST failed" + ex.getMessage());
- }
- }
- }
-
- /** Abstract SOAP Servlet */
+ /** Abstract SOAP Servlet */
private abstract static class AbstractSoapServlet extends HttpServlet {
protected MessageFactory messageFactory = null;
@@ -386,9 +301,7 @@ public class WebServiceTemplateIntegrationTest {
resp.setStatus(sc);
}
if (reply != null) {
- if (reply.saveRequired()) {
- reply.saveChanges();
- }
+ reply.saveChanges();
if (sc == -1) {
resp.setStatus(!reply.getSOAPBody().hasFault() ? HttpServletResponse.SC_OK :
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
diff --git a/spring-ws-core/src/test/java/org/springframework/ws/client/core/AbstractSoap12WebServiceTemplateIntegrationTestCase.java b/spring-ws-core/src/test/java/org/springframework/ws/client/core/AbstractSoap12WebServiceTemplateIntegrationTestCase.java
new file mode 100644
index 00000000..ba4ae011
--- /dev/null
+++ b/spring-ws-core/src/test/java/org/springframework/ws/client/core/AbstractSoap12WebServiceTemplateIntegrationTestCase.java
@@ -0,0 +1,408 @@
+/*
+ * Copyright 2005-2014 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.client.core;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+import javax.activation.CommandMap;
+import javax.activation.DataHandler;
+import javax.activation.MailcapCommandMap;
+import javax.mail.util.ByteArrayDataSource;
+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.soap.MessageFactory;
+import javax.xml.soap.MimeHeader;
+import javax.xml.soap.MimeHeaders;
+import javax.xml.soap.SOAPBody;
+import javax.xml.soap.SOAPConstants;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import static org.junit.Assert.assertEquals;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.servlet.Context;
+import org.mortbay.jetty.servlet.ServletHolder;
+import org.xml.sax.SAXException;
+
+import org.springframework.oxm.Marshaller;
+import org.springframework.oxm.Unmarshaller;
+import org.springframework.oxm.XmlMappingException;
+import org.springframework.ws.WebServiceMessage;
+import org.springframework.ws.client.WebServiceTransportException;
+import org.springframework.ws.soap.SoapMessage;
+import org.springframework.ws.soap.SoapMessageFactory;
+import org.springframework.ws.soap.client.SoapFaultClientException;
+import org.springframework.ws.transport.http.HttpComponentsMessageSender;
+import org.springframework.ws.transport.support.FreePortScanner;
+import org.springframework.xml.transform.StringResult;
+import org.springframework.xml.transform.StringSource;
+
+public abstract class AbstractSoap12WebServiceTemplateIntegrationTestCase {
+
+ private static Server jettyServer;
+
+ private static String baseUrl;
+
+
+ private WebServiceTemplate template;
+
+ private String messagePayload = "";
+
+ @BeforeClass
+ public static void startJetty() throws Exception {
+ int port = FreePortScanner.getFreePort();
+ baseUrl = "http://localhost:" + port;
+ jettyServer = new Server(port);
+ Context jettyContext = new Context(jettyServer, "/");
+ jettyContext.addServlet(new ServletHolder(new EchoSoapServlet()), "/soap/echo");
+ jettyContext.addServlet(new ServletHolder(new SoapReceiverFaultServlet()), "/soap/receiverFault");
+ jettyContext.addServlet(new ServletHolder(new SoapSenderFaultServlet()), "/soap/senderFault");
+ jettyContext.addServlet(new ServletHolder(new NoResponseSoapServlet()), "/soap/noResponse");
+ jettyContext.addServlet(new ServletHolder(new AttachmentsServlet()), "/soap/attachment");
+ jettyContext.addServlet(new ServletHolder(new ErrorServlet(404)), "/errors/notfound");
+ jettyContext.addServlet(new ServletHolder(new ErrorServlet(500)), "/errors/server");
+ jettyServer.start();
+ }
+
+ @AfterClass
+ public static void stopJetty() throws Exception {
+ if (jettyServer.isRunning()) {
+ jettyServer.stop();
+ }
+ }
+
+ /**
+ * A workaround for the faulty XmlDataContentHandler in the SAAJ RI, which cannot handle mime types such as
+ * "text/xml; charset=UTF-8", causing issues with Axiom. We basically reset the command map
+ */
+ @Before
+ public void removeXmlDataContentHandler() throws SOAPException {
+ MessageFactory messageFactory = MessageFactory.newInstance();
+ SOAPMessage message = messageFactory.createMessage();
+ message.createAttachmentPart();
+ CommandMap.setDefaultCommandMap(new MailcapCommandMap());
+ }
+
+ @Before
+ public void createWebServiceTemplate() throws Exception {
+ template = new WebServiceTemplate(createMessageFactory());
+ template.setMessageSender(new HttpComponentsMessageSender());
+ }
+
+
+ public abstract SoapMessageFactory createMessageFactory() throws Exception;
+
+ @Test
+ public void sendSourceAndReceiveToResult() throws SAXException, IOException {
+ StringResult result = new StringResult();
+ boolean b = template.sendSourceAndReceiveToResult(baseUrl + "/soap/echo",
+ new StringSource(messagePayload), result);
+ Assert.assertTrue("Invalid result", b);
+ assertXMLEqual(messagePayload, result.toString());
+ }
+
+ @Test
+ public void sendSourceAndReceiveToResultNoResponse() {
+ boolean b = template.sendSourceAndReceiveToResult(baseUrl + "/soap/noResponse",
+ new StringSource(messagePayload), new StringResult());
+ Assert.assertFalse("Invalid result", b);
+ }
+
+ @Test
+ public void marshalSendAndReceiveResponse() throws TransformerConfigurationException {
+ final Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ final Object requestObject = new Object();
+ Marshaller marshaller = new Marshaller() {
+
+ @Override
+ public void marshal(Object graph, Result result) throws XmlMappingException, IOException {
+ Assert.assertEquals("Invalid object", graph, requestObject);
+ try {
+ transformer.transform(new StringSource(messagePayload), result);
+ }
+ catch (TransformerException e) {
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ @Override
+ public boolean supports(Class> clazz) {
+ Assert.assertEquals("Invalid class", Object.class, clazz);
+ return true;
+ }
+ };
+ final Object responseObject = new Object();
+ Unmarshaller unmarshaller = new Unmarshaller() {
+
+ @Override
+ public Object unmarshal(Source source) throws XmlMappingException, IOException {
+ return responseObject;
+ }
+
+ @Override
+ public boolean supports(Class> clazz) {
+ Assert.assertEquals("Invalid class", Object.class, clazz);
+ return true;
+ }
+ };
+ template.setMarshaller(marshaller);
+ template.setUnmarshaller(unmarshaller);
+ Object result = template.marshalSendAndReceive(baseUrl + "/soap/echo", requestObject);
+ Assert.assertEquals("Invalid response object", responseObject, result);
+ }
+
+ @Test
+ public void marshalSendAndReceiveNoResponse() throws TransformerConfigurationException {
+ final Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ final Object requestObject = new Object();
+ Marshaller marshaller = new Marshaller() {
+
+ @Override
+ public void marshal(Object graph, Result result) throws XmlMappingException, IOException {
+ Assert.assertEquals("Invalid object", graph, requestObject);
+ try {
+ transformer.transform(new StringSource(messagePayload), result);
+ }
+ catch (TransformerException e) {
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ @Override
+ public boolean supports(Class> clazz) {
+ Assert.assertEquals("Invalid class", Object.class, clazz);
+ return true;
+ }
+ };
+ template.setMarshaller(marshaller);
+ Object result = template.marshalSendAndReceive(baseUrl + "/soap/noResponse", requestObject);
+ Assert.assertNull("Invalid response object", result);
+ }
+
+ @Test
+ public void notFound() {
+ try {
+ template.sendSourceAndReceiveToResult(baseUrl + "/errors/notfound",
+ new StringSource(messagePayload), new StringResult());
+ Assert.fail("WebServiceTransportException expected");
+ }
+ catch (WebServiceTransportException ex) {
+ //expected
+ }
+ }
+
+ @Test
+ public void receiverFault() {
+ Result result = new StringResult();
+ try {
+ template.sendSourceAndReceiveToResult(baseUrl + "/soap/receiverFault", new StringSource(messagePayload),
+ result);
+ Assert.fail("SoapFaultClientException expected");
+ }
+ catch (SoapFaultClientException ex) {
+ //expected
+ }
+ }
+
+ @Test
+ public void senderFault() {
+ Result result = new StringResult();
+ try {
+ template.sendSourceAndReceiveToResult(baseUrl + "/soap/senderFault", new StringSource(messagePayload),
+ result);
+ Assert.fail("SoapFaultClientException expected");
+ }
+ catch (SoapFaultClientException ex) {
+ //expected
+ }
+ }
+
+ @Test
+ public void attachment() {
+ template.sendSourceAndReceiveToResult(baseUrl + "/soap/attachment", new StringSource(messagePayload),
+ new WebServiceMessageCallback() {
+
+ @Override
+ public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
+ SoapMessage soapMessage = (SoapMessage) message;
+ final String attachmentContent = "content";
+ soapMessage.addAttachment("attachment-1",
+ new DataHandler(new ByteArrayDataSource(attachmentContent, "text/plain")));
+ }
+ }, new StringResult());
+ }
+
+ /** Servlet that returns and error message for a given status code. */
+ private static class ErrorServlet extends HttpServlet {
+
+ private int sc;
+
+ private ErrorServlet(int sc) {
+ this.sc = sc;
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ resp.sendError(sc);
+ }
+ }
+
+ /** Abstract SOAP Servlet */
+ private abstract static class AbstractSoapServlet extends HttpServlet {
+
+ protected MessageFactory messageFactory = null;
+
+ private final int sc = -1;
+
+ @Override
+ public void init(ServletConfig servletConfig) throws ServletException {
+ super.init(servletConfig);
+ try {
+ messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
+ }
+ catch (SOAPException ex) {
+ throw new ServletException("Unable to create message factory" + ex.getMessage());
+ }
+ }
+
+ @Override
+ public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ try {
+ MimeHeaders headers = getHeaders(req);
+ SOAPMessage request = messageFactory.createMessage(headers, req.getInputStream());
+ SOAPMessage reply = onMessage(request);
+ if (reply != null) {
+ reply.saveChanges();
+ SOAPBody replyBody = reply.getSOAPBody();
+ if (!replyBody.hasFault()) {
+ resp.setStatus(HttpServletResponse.SC_OK);
+ }
+ else {
+ if (replyBody.getFault().getFaultCodeAsQName()
+ .equals(SOAPConstants.SOAP_SENDER_FAULT)) {
+ resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+
+ }
+ else {
+ resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+ }
+ putHeaders(reply.getMimeHeaders(), resp);
+ reply.writeTo(resp.getOutputStream());
+ }
+ else {
+ resp.setStatus(HttpServletResponse.SC_ACCEPTED);
+ }
+ }
+ catch (Exception ex) {
+ throw new ServletException("SAAJ POST failed " + ex.getMessage(), ex);
+ }
+ }
+
+ 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());
+ for (String value : values) {
+ res.addHeader(header.getName(), value);
+ }
+ }
+ }
+
+ protected abstract SOAPMessage onMessage(SOAPMessage message) throws SOAPException;
+ }
+
+ private static class EchoSoapServlet extends AbstractSoapServlet {
+
+ @Override
+ protected SOAPMessage onMessage(SOAPMessage message) throws SOAPException {
+ return message;
+ }
+ }
+
+ private static class NoResponseSoapServlet extends AbstractSoapServlet {
+
+ @Override
+ protected SOAPMessage onMessage(SOAPMessage message) throws SOAPException {
+ return null;
+ }
+ }
+
+ private static class SoapReceiverFaultServlet extends AbstractSoapServlet {
+
+ @Override
+ protected SOAPMessage onMessage(SOAPMessage message) throws SOAPException {
+ SOAPMessage response = messageFactory.createMessage();
+ SOAPBody body = response.getSOAPBody();
+ body.addFault(SOAPConstants.SOAP_RECEIVER_FAULT, "Receiver Fault");
+ return response;
+ }
+ }
+
+ private static class SoapSenderFaultServlet extends AbstractSoapServlet {
+
+ @Override
+ protected SOAPMessage onMessage(SOAPMessage message) throws SOAPException {
+ SOAPMessage response = messageFactory.createMessage();
+ SOAPBody body = response.getSOAPBody();
+ body.addFault(SOAPConstants.SOAP_SENDER_FAULT, "Sender Fault");
+ return response;
+ }
+ }
+
+ private static class AttachmentsServlet extends AbstractSoapServlet {
+
+ @Override
+ protected SOAPMessage onMessage(SOAPMessage message) throws SOAPException {
+ assertEquals("No attachments found", 1, message.countAttachments());
+ return null;
+ }
+ }
+
+}
diff --git a/spring-ws-core/src/test/java/org/springframework/ws/client/core/AxiomNonStreamingSoap11WebServiceTemplateIntegrationTest.java b/spring-ws-core/src/test/java/org/springframework/ws/client/core/AxiomNonStreamingSoap11WebServiceTemplateIntegrationTest.java
new file mode 100644
index 00000000..08071109
--- /dev/null
+++ b/spring-ws-core/src/test/java/org/springframework/ws/client/core/AxiomNonStreamingSoap11WebServiceTemplateIntegrationTest.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2005-2014 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.client.core;
+
+import org.springframework.ws.soap.SoapMessageFactory;
+import org.springframework.ws.soap.axiom.AxiomSoapMessageFactory;
+
+/**
+ * @author Arjen Poutsma
+ */
+public class AxiomNonStreamingSoap11WebServiceTemplateIntegrationTest
+ extends AbstractSoap11WebServiceTemplateIntegrationTestCase {
+
+ @Override
+ public SoapMessageFactory createMessageFactory() throws Exception {
+ return new AxiomSoapMessageFactory();
+ }
+}
diff --git a/spring-ws-core/src/test/java/org/springframework/ws/client/core/AxiomNonStreamingSoap12WebServiceTemplateIntegrationTest.java b/spring-ws-core/src/test/java/org/springframework/ws/client/core/AxiomNonStreamingSoap12WebServiceTemplateIntegrationTest.java
new file mode 100644
index 00000000..503d5d3d
--- /dev/null
+++ b/spring-ws-core/src/test/java/org/springframework/ws/client/core/AxiomNonStreamingSoap12WebServiceTemplateIntegrationTest.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2005-2014 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.client.core;
+
+import org.springframework.ws.soap.SoapMessageFactory;
+import org.springframework.ws.soap.SoapVersion;
+import org.springframework.ws.soap.axiom.AxiomSoapMessageFactory;
+
+/**
+ * @author Arjen Poutsma
+ */
+public class AxiomNonStreamingSoap12WebServiceTemplateIntegrationTest
+ extends AbstractSoap12WebServiceTemplateIntegrationTestCase {
+
+ @Override
+ public SoapMessageFactory createMessageFactory() throws Exception {
+ AxiomSoapMessageFactory messageFactory = new AxiomSoapMessageFactory();
+ messageFactory.setSoapVersion(SoapVersion.SOAP_12);
+ return messageFactory;
+ }
+}
diff --git a/spring-ws-core/src/test/java/org/springframework/ws/client/core/AxiomStreamingSoap11WebServiceTemplateIntegrationTest.java b/spring-ws-core/src/test/java/org/springframework/ws/client/core/AxiomStreamingSoap11WebServiceTemplateIntegrationTest.java
new file mode 100644
index 00000000..22b44509
--- /dev/null
+++ b/spring-ws-core/src/test/java/org/springframework/ws/client/core/AxiomStreamingSoap11WebServiceTemplateIntegrationTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2005-2014 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.client.core;
+
+import org.springframework.ws.soap.SoapMessageFactory;
+import org.springframework.ws.soap.axiom.AxiomSoapMessageFactory;
+
+/**
+ * @author Arjen Poutsma
+ */
+public class AxiomStreamingSoap11WebServiceTemplateIntegrationTest
+ extends AbstractSoap11WebServiceTemplateIntegrationTestCase {
+
+ @Override
+ public SoapMessageFactory createMessageFactory() throws Exception {
+ AxiomSoapMessageFactory axiomFactory = new AxiomSoapMessageFactory();
+ axiomFactory.setPayloadCaching(false);
+ return axiomFactory;
+ }
+}
diff --git a/spring-ws-core/src/test/java/org/springframework/ws/client/core/AxiomStreamingSoap12WebServiceTemplateIntegrationTest.java b/spring-ws-core/src/test/java/org/springframework/ws/client/core/AxiomStreamingSoap12WebServiceTemplateIntegrationTest.java
new file mode 100644
index 00000000..34cd448e
--- /dev/null
+++ b/spring-ws-core/src/test/java/org/springframework/ws/client/core/AxiomStreamingSoap12WebServiceTemplateIntegrationTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2005-2014 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.client.core;
+
+import org.springframework.ws.soap.SoapMessageFactory;
+import org.springframework.ws.soap.SoapVersion;
+import org.springframework.ws.soap.axiom.AxiomSoapMessageFactory;
+
+/**
+ * @author Arjen Poutsma
+ */
+public class AxiomStreamingSoap12WebServiceTemplateIntegrationTest
+ extends AbstractSoap12WebServiceTemplateIntegrationTestCase {
+
+ @Override
+ public SoapMessageFactory createMessageFactory() throws Exception {
+ AxiomSoapMessageFactory axiomFactory = new AxiomSoapMessageFactory();
+ axiomFactory.setSoapVersion(SoapVersion.SOAP_12);
+ axiomFactory.setPayloadCaching(false);
+ return axiomFactory;
+ }
+}
diff --git a/spring-ws-core/src/test/java/org/springframework/ws/client/core/DomPoxWebServiceTemplateIntegrationTest.java b/spring-ws-core/src/test/java/org/springframework/ws/client/core/DomPoxWebServiceTemplateIntegrationTest.java
new file mode 100644
index 00000000..f256066c
--- /dev/null
+++ b/spring-ws-core/src/test/java/org/springframework/ws/client/core/DomPoxWebServiceTemplateIntegrationTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2005-2014 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.client.core;
+
+import java.io.IOException;
+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.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.servlet.Context;
+import org.mortbay.jetty.servlet.ServletHolder;
+import org.w3c.dom.Document;
+
+import org.springframework.ws.client.WebServiceTransportException;
+import org.springframework.ws.pox.dom.DomPoxMessageFactory;
+import org.springframework.ws.transport.http.HttpComponentsMessageSender;
+import org.springframework.ws.transport.support.FreePortScanner;
+import org.springframework.xml.transform.StringResult;
+import org.springframework.xml.transform.StringSource;
+
+public class DomPoxWebServiceTemplateIntegrationTest {
+
+ private static Server jettyServer;
+
+ private static String baseUrl;
+
+ @BeforeClass
+ public static void startJetty() throws Exception {
+ int port = FreePortScanner.getFreePort();
+ baseUrl = "http://localhost:" + port;
+ jettyServer = new Server(port);
+ Context jettyContext = new Context(jettyServer, "/");
+ 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();
+ }
+
+ @AfterClass
+ public static void stopJetty() throws Exception {
+ if (jettyServer.isRunning()) {
+ jettyServer.stop();
+ }
+ }
+
+ @Test
+ public void domPox() throws Exception {
+ WebServiceTemplate template = new WebServiceTemplate(new DomPoxMessageFactory());
+ template.setMessageSender(new HttpComponentsMessageSender());
+ String content = "";
+ StringResult result = new StringResult();
+ template.sendSourceAndReceiveToResult(baseUrl + "/pox", new StringSource(content),
+ result);
+ assertXMLEqual(content, result.toString());
+ try {
+ template.sendSourceAndReceiveToResult(baseUrl + "/errors/notfound",
+ new StringSource(content), new StringResult());
+ Assert.fail("WebServiceTransportException expected");
+ }
+ catch (WebServiceTransportException ex) {
+ //expected
+ }
+ try {
+ template.sendSourceAndReceiveToResult(baseUrl + "/errors/server",
+ new StringSource(content), result);
+ Assert.fail("WebServiceTransportException expected");
+ }
+ catch (WebServiceTransportException ex) {
+ //expected
+ }
+ }
+
+ /** Servlet that returns and error message for a given status code. */
+ private static class ErrorServlet extends HttpServlet {
+
+ private int sc;
+
+ private ErrorServlet(int sc) {
+ this.sc = sc;
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ resp.sendError(sc);
+ }
+ }
+
+ /** Simple POX Servlet. */
+ private static class PoxServlet extends HttpServlet {
+
+ private DocumentBuilderFactory documentBuilderFactory;
+
+ private TransformerFactory transformerFactory;
+
+ @Override
+ public void init(ServletConfig servletConfig) throws ServletException {
+ super.init(servletConfig);
+ documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ transformerFactory = TransformerFactory.newInstance();
+ }
+
+ @Override
+ public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ try {
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+ Document message = documentBuilder.parse(req.getInputStream());
+ Transformer transformer = transformerFactory.newTransformer();
+ transformer.transform(new DOMSource(message), new StreamResult(resp.getOutputStream()));
+ }
+ catch (Exception ex) {
+ throw new ServletException("POX POST failed" + ex.getMessage());
+ }
+ }
+ }
+
+}
diff --git a/spring-ws-core/src/test/java/org/springframework/ws/client/core/SaajSoap11WebServiceTemplateIntegrationTest.java b/spring-ws-core/src/test/java/org/springframework/ws/client/core/SaajSoap11WebServiceTemplateIntegrationTest.java
new file mode 100644
index 00000000..5fa55161
--- /dev/null
+++ b/spring-ws-core/src/test/java/org/springframework/ws/client/core/SaajSoap11WebServiceTemplateIntegrationTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2005-2014 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.client.core;
+
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPConstants;
+
+import org.springframework.ws.soap.SoapMessageFactory;
+import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
+
+/**
+ * @author Arjen Poutsma
+ */
+public class SaajSoap11WebServiceTemplateIntegrationTest
+ extends AbstractSoap11WebServiceTemplateIntegrationTestCase {
+
+ @Override
+ public SoapMessageFactory createMessageFactory() throws Exception {
+ MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
+ return new SaajSoapMessageFactory(messageFactory);
+ }
+}
diff --git a/spring-ws-core/src/test/java/org/springframework/ws/client/core/SaajSoap12WebServiceTemplateIntegrationTest.java b/spring-ws-core/src/test/java/org/springframework/ws/client/core/SaajSoap12WebServiceTemplateIntegrationTest.java
new file mode 100644
index 00000000..496adf3a
--- /dev/null
+++ b/spring-ws-core/src/test/java/org/springframework/ws/client/core/SaajSoap12WebServiceTemplateIntegrationTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2005-2014 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.client.core;
+
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPConstants;
+
+import org.springframework.ws.soap.SoapMessageFactory;
+import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
+
+/**
+ * @author Arjen Poutsma
+ */
+public class SaajSoap12WebServiceTemplateIntegrationTest
+ extends AbstractSoap12WebServiceTemplateIntegrationTestCase {
+
+ @Override
+ public SoapMessageFactory createMessageFactory() throws Exception {
+ MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
+ return new SaajSoapMessageFactory(messageFactory);
+ }
+}
diff --git a/spring-ws-core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateTest.java b/spring-ws-core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateTest.java
index da78f171..b4d22a45 100644
--- a/spring-ws-core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateTest.java
+++ b/spring-ws-core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2010 the original author or authors.
+ * Copyright 2005-2014 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.
@@ -21,6 +21,11 @@ import java.net.URI;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+import org.junit.Before;
+import org.junit.Test;
+
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;
import org.springframework.ws.MockWebServiceMessage;
@@ -37,12 +42,6 @@ import org.springframework.ws.transport.WebServiceMessageSender;
import org.springframework.xml.transform.StringResult;
import org.springframework.xml.transform.StringSource;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.easymock.EasyMock.*;
-import static org.junit.Assert.*;
-
public class WebServiceTemplateTest {
private WebServiceTemplate template;
@@ -60,10 +59,12 @@ public class WebServiceTemplateTest {
expect(connectionMock.getUri()).andReturn(expectedUri).anyTimes();
template.setMessageSender(new WebServiceMessageSender() {
+ @Override
public WebServiceConnection createConnection(URI uri) throws IOException {
return connectionMock;
}
+ @Override
public boolean supports(URI uri) {
assertEquals("Invalid uri", expectedUri, uri);
return true;
@@ -339,10 +340,12 @@ public class WebServiceTemplateTest {
final URI customUri = new URI("http://www.springframework.org/spring-ws/custom");
template.setMessageSender(new WebServiceMessageSender() {
+ @Override
public WebServiceConnection createConnection(URI uri) throws IOException {
return connectionMock;
}
+ @Override
public boolean supports(URI uri) {
assertEquals("Invalid uri", customUri, uri);
return true;
@@ -472,10 +475,12 @@ public class WebServiceTemplateTest {
template.setMessageSender(new WebServiceMessageSender() {
+ @Override
public WebServiceConnection createConnection(URI uri) throws IOException {
return connectionMock;
}
+ @Override
public boolean supports(URI uri) {
assertEquals("Invalid uri", providerUri, uri);
return true;
diff --git a/spring-ws-core/src/test/java/org/springframework/ws/transport/http/HttpServletConnectionTest.java b/spring-ws-core/src/test/java/org/springframework/ws/transport/http/HttpServletConnectionTest.java
index d1f87200..5958af71 100644
--- a/spring-ws-core/src/test/java/org/springframework/ws/transport/http/HttpServletConnectionTest.java
+++ b/spring-ws-core/src/test/java/org/springframework/ws/transport/http/HttpServletConnectionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2010 the original author or authors.
+ * Copyright 2005-2014 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.
@@ -16,6 +16,7 @@
package org.springframework.ws.transport.http;
+import java.io.IOException;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPConstants;
@@ -23,19 +24,20 @@ import javax.xml.soap.SOAPMessage;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import org.junit.Assert;
+import static org.junit.Assert.assertEquals;
+import org.junit.Before;
+import org.junit.Test;
+
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.ws.soap.SoapVersion;
import org.springframework.ws.soap.saaj.SaajSoapMessage;
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
import org.springframework.xml.transform.StringResult;
import org.springframework.xml.transform.StringSource;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
-
public class HttpServletConnectionTest {
private HttpServletConnection connection;
@@ -69,7 +71,7 @@ public class HttpServletConnectionTest {
}
@Test
- public void testReceive() throws Exception {
+ public void receive() throws Exception {
byte[] bytes = SOAP_CONTENT.getBytes("UTF-8");
httpServletRequest.addHeader("Content-Type", "text/xml");
httpServletRequest.addHeader("Content-Length", Integer.toString(bytes.length));
@@ -84,13 +86,13 @@ public class HttpServletConnectionTest {
SOAPMessage saajMessage = message.getSaajMessage();
String[] headerValues = saajMessage.getMimeHeaders().getHeader(HEADER_NAME);
Assert.assertNotNull("Response has no header", headerValues);
- Assert.assertEquals("Response has invalid header", 1, headerValues.length);
- Assert.assertEquals("Response has invalid header values", HEADER_VALUE, headerValues[0]);
+ assertEquals("Response has invalid header", 1, headerValues.length);
+ assertEquals("Response has invalid header values", HEADER_VALUE, headerValues[0]);
}
@Test
- public void testSend() throws Exception {
- SaajSoapMessage message = (SaajSoapMessage) messageFactory.createWebServiceMessage();
+ public void send() throws Exception {
+ SaajSoapMessage message = messageFactory.createWebServiceMessage();
SOAPMessage saajMessage = message.getSaajMessage();
MimeHeaders mimeHeaders = saajMessage.getMimeHeaders();
mimeHeaders.addHeader(HEADER_NAME, HEADER_VALUE);
@@ -99,8 +101,24 @@ public class HttpServletConnectionTest {
connection.send(message);
- Assert.assertEquals("Invalid header", HEADER_VALUE, httpServletResponse.getHeader(HEADER_NAME));
+ assertEquals("Invalid header", HEADER_VALUE,
+ httpServletResponse.getHeader(HEADER_NAME));
assertXMLEqual("Invalid content", SOAP_CONTENT, httpServletResponse.getContentAsString());
}
+ @Test
+ public void faultCodes() throws IOException {
+ connection.setFaultCode(SoapVersion.SOAP_11.getClientOrSenderFaultName());
+ assertEquals(500, httpServletResponse.getStatus());
+
+ connection.setFaultCode(SoapVersion.SOAP_11.getServerOrReceiverFaultName());
+ assertEquals(500, httpServletResponse.getStatus());
+
+ connection.setFaultCode(SoapVersion.SOAP_12.getClientOrSenderFaultName());
+ assertEquals(400, httpServletResponse.getStatus());
+
+ connection.setFaultCode(SoapVersion.SOAP_12.getServerOrReceiverFaultName());
+ assertEquals(500, httpServletResponse.getStatus());
+ }
+
}
\ No newline at end of file
diff --git a/spring-ws-core/src/test/java/org/springframework/ws/transport/http/WebServiceMessageReceiverHandlerAdapterTest.java b/spring-ws-core/src/test/java/org/springframework/ws/transport/http/WebServiceMessageReceiverHandlerAdapterTest.java
index 9f34ccd2..2a4c95d3 100644
--- a/spring-ws-core/src/test/java/org/springframework/ws/transport/http/WebServiceMessageReceiverHandlerAdapterTest.java
+++ b/spring-ws-core/src/test/java/org/springframework/ws/transport/http/WebServiceMessageReceiverHandlerAdapterTest.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2005-2012 the original author or authors.
+ * Copyright 2005-2014 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
+ * 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,
@@ -20,6 +20,11 @@ import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.http.HttpServletResponse;
+import static org.easymock.EasyMock.*;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.ws.FaultAwareWebServiceMessage;
@@ -27,14 +32,9 @@ import org.springframework.ws.InvalidXmlException;
import org.springframework.ws.NoEndpointFoundException;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.context.MessageContext;
+import org.springframework.ws.soap.SoapVersion;
import org.springframework.ws.transport.WebServiceMessageReceiver;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.easymock.EasyMock.*;
-
public class WebServiceMessageReceiverHandlerAdapterTest {
private static final String REQUEST = "