diff --git a/core/src/main/java/org/springframework/ws/WebServiceMessageFactory.java b/core/src/main/java/org/springframework/ws/WebServiceMessageFactory.java
index 80466119..0260b95c 100644
--- a/core/src/main/java/org/springframework/ws/WebServiceMessageFactory.java
+++ b/core/src/main/java/org/springframework/ws/WebServiceMessageFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006-2007 the original author or authors.
+ * Copyright 2002-2010 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,7 +44,7 @@ public interface WebServiceMessageFactory {
* If the given stream is an instance of {@link org.springframework.ws.transport.TransportInputStream
* TransportInputStream}, the headers will be read from the request.
*
- * @param inputStream the inputstream to read the message from
+ * @param inputStream the input stream to read the message from
* @return the created message
* @throws java.io.IOException if an I/O exception occurs
*/
diff --git a/core/src/main/java/org/springframework/ws/soap/SoapMessageFactory.java b/core/src/main/java/org/springframework/ws/soap/SoapMessageFactory.java
index f3c442e8..aaf1d6ef 100644
--- a/core/src/main/java/org/springframework/ws/soap/SoapMessageFactory.java
+++ b/core/src/main/java/org/springframework/ws/soap/SoapMessageFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2002-2010 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,9 @@
package org.springframework.ws.soap;
+import java.io.IOException;
+import java.io.InputStream;
+
import org.springframework.ws.WebServiceMessageFactory;
/**
@@ -38,4 +41,24 @@ public interface SoapMessageFactory extends WebServiceMessageFactory {
*/
void setSoapVersion(SoapVersion version);
+ /**
+ * Creates a new, empty SoapMessage.
+ *
+ * @return the empty message
+ */
+ SoapMessage createWebServiceMessage();
+
+ /**
+ * Reads a {@link SoapMessage} from the given input stream.
+ *
+ * If the given stream is an instance of {@link org.springframework.ws.transport.TransportInputStream
+ * TransportInputStream}, the headers will be read from the request.
+ *
+ * @param inputStream the input stream to read the message from
+ * @return the created message
+ * @throws java.io.IOException if an I/O exception occurs
+ */
+ SoapMessage createWebServiceMessage(InputStream inputStream) throws IOException;
+
+
}
diff --git a/core/src/main/java/org/springframework/ws/soap/axiom/AxiomSoapMessageFactory.java b/core/src/main/java/org/springframework/ws/soap/axiom/AxiomSoapMessageFactory.java
index 0944f5e4..13f41776 100644
--- a/core/src/main/java/org/springframework/ws/soap/axiom/AxiomSoapMessageFactory.java
+++ b/core/src/main/java/org/springframework/ws/soap/axiom/AxiomSoapMessageFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2010 the original author or authors.
+ * Copyright 2002-2010 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.
@@ -28,7 +28,6 @@ import javax.xml.stream.XMLStreamReader;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
-import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor;
import org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping;
import org.springframework.ws.soap.SoapMessageFactory;
@@ -191,11 +190,11 @@ public class AxiomSoapMessageFactory implements SoapMessageFactory, Initializing
}
}
- public WebServiceMessage createWebServiceMessage() {
+ public AxiomSoapMessage createWebServiceMessage() {
return new AxiomSoapMessage(soapFactory, payloadCaching, langAttributeOnSoap11FaultString);
}
- public WebServiceMessage createWebServiceMessage(InputStream inputStream) throws IOException {
+ public AxiomSoapMessage createWebServiceMessage(InputStream inputStream) throws IOException {
Assert.isInstanceOf(TransportInputStream.class, inputStream,
"AxiomSoapMessageFactory requires a TransportInputStream");
TransportInputStream transportInputStream = (TransportInputStream) inputStream;
@@ -242,7 +241,7 @@ public class AxiomSoapMessageFactory implements SoapMessageFactory, Initializing
}
/** Creates an AxiomSoapMessage without attachments. */
- private WebServiceMessage createAxiomSoapMessage(InputStream inputStream, String contentType, String soapAction)
+ private AxiomSoapMessage createAxiomSoapMessage(InputStream inputStream, String contentType, String soapAction)
throws XMLStreamException {
XMLStreamReader reader = inputFactory.createXMLStreamReader(inputStream, getCharSetEncoding(contentType));
String envelopeNamespace = getSoapEnvelopeNamespace(contentType);
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 21587ac7..fa05dee0 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2010 the original author or authors.
+ * Copyright 2002-2010 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,15 +21,17 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.util.Iterator;
+import java.util.Map;
import java.util.StringTokenizer;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
import org.springframework.beans.factory.InitializingBean;
+import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
-import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.soap.SoapMessageCreationException;
import org.springframework.ws.soap.SoapMessageFactory;
import org.springframework.ws.soap.SoapVersion;
@@ -63,6 +65,8 @@ public class SaajSoapMessageFactory implements SoapMessageFactory, InitializingB
private boolean langAttributeOnSoap11FaultString = true;
+ private Map messageProperties;
+
/** Default, empty constructor. */
public SaajSoapMessageFactory() {
}
@@ -82,6 +86,14 @@ public class SaajSoapMessageFactory implements SoapMessageFactory, InitializingB
this.messageFactory = messageFactory;
}
+ /**
+ * Sets the SAAJ message properties. These properties will be set on created messages.
+ * @see javax.xml.soap.SOAPMessage#setProperty(String, Object)
+ */
+ public void setMessageProperties(Map messageProperties) {
+ this.messageProperties = messageProperties;
+ }
+
/**
* Defines whether a {@code xml:lang} attribute should be set on SOAP 1.1 {@code } elements.
*
@@ -90,7 +102,7 @@ public class SaajSoapMessageFactory implements SoapMessageFactory, InitializingB
*
* @see WS-I Basic Profile 1.1
*/
- public void setlangAttributeOnSoap11FaultString(boolean langAttributeOnSoap11FaultString) {
+ public void setLangAttributeOnSoap11FaultString(boolean langAttributeOnSoap11FaultString) {
this.langAttributeOnSoap11FaultString = langAttributeOnSoap11FaultString;
}
@@ -152,20 +164,24 @@ public class SaajSoapMessageFactory implements SoapMessageFactory, InitializingB
}
}
- public WebServiceMessage createWebServiceMessage() {
+ public SaajSoapMessage createWebServiceMessage() {
try {
- return new SaajSoapMessage(messageFactory.createMessage(), langAttributeOnSoap11FaultString);
+ SOAPMessage saajMessage = messageFactory.createMessage();
+ postProcess(saajMessage);
+ return new SaajSoapMessage(saajMessage, langAttributeOnSoap11FaultString);
}
catch (SOAPException ex) {
throw new SoapMessageCreationException("Could not create empty message: " + ex.getMessage(), ex);
}
}
- public WebServiceMessage createWebServiceMessage(InputStream inputStream) throws IOException {
+ public SaajSoapMessage createWebServiceMessage(InputStream inputStream) throws IOException {
MimeHeaders mimeHeaders = parseMimeHeaders(inputStream);
try {
inputStream = checkForUtf8ByteOrderMark(inputStream);
- return new SaajSoapMessage(messageFactory.createMessage(mimeHeaders, inputStream));
+ SOAPMessage saajMessage = messageFactory.createMessage(mimeHeaders, inputStream);
+ postProcess(saajMessage);
+ return new SaajSoapMessage(saajMessage);
}
catch (SOAPException ex) {
// SAAJ 1.3 RI has a issue with handling multipart XOP content types which contain "startinfo" rather than
@@ -176,7 +192,9 @@ public class SaajSoapMessageFactory implements SoapMessageFactory, InitializingB
contentType = contentType.replace("startinfo", "start-info");
mimeHeaders.setHeader(TransportConstants.HEADER_CONTENT_TYPE, contentType);
try {
- return new SaajSoapMessage(messageFactory.createMessage(mimeHeaders, inputStream),
+ SOAPMessage saajMessage = messageFactory.createMessage(mimeHeaders, inputStream);
+ postProcess(saajMessage);
+ return new SaajSoapMessage(saajMessage,
langAttributeOnSoap11FaultString);
}
catch (SOAPException e) {
@@ -223,6 +241,20 @@ public class SaajSoapMessageFactory implements SoapMessageFactory, InitializingB
return pushbackInputStream;
}
+ /**
+ * Template method that allows for post-processing of the given {@link SOAPMessage}.
+ * Default implementation sets {@linkplain SOAPMessage#setProperty(String, Object) message properties}, if any.
+ * @param soapMessage the message to post process
+ * @see #setMessageProperties(java.util.Map)
+ */
+ protected void postProcess(SOAPMessage soapMessage) throws SOAPException {
+ if (!CollectionUtils.isEmpty(messageProperties)) {
+ for (Map.Entry entry : messageProperties.entrySet()) {
+ soapMessage.setProperty(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+
public String toString() {
StringBuilder builder = new StringBuilder("SaajSoapMessageFactory[");
builder.append(SaajUtils.getSaajVersionString());
diff --git a/core/src/test/java/org/springframework/ws/soap/saaj/SaajSoap11MessageFactoryTest.java b/core/src/test/java/org/springframework/ws/soap/saaj/SaajSoap11MessageFactoryTest.java
index e791534d..788abd38 100644
--- a/core/src/test/java/org/springframework/ws/soap/saaj/SaajSoap11MessageFactoryTest.java
+++ b/core/src/test/java/org/springframework/ws/soap/saaj/SaajSoap11MessageFactoryTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2010 the original author or authors.
+ * Copyright 2002-2010 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,12 +16,22 @@
package org.springframework.ws.soap.saaj;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPConstants;
+import javax.xml.soap.SOAPMessage;
import org.springframework.ws.WebServiceMessageFactory;
+import org.springframework.ws.soap.SoapMessage;
import org.springframework.ws.soap.soap11.AbstractSoap11MessageFactoryTestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
public class SaajSoap11MessageFactoryTest extends AbstractSoap11MessageFactoryTestCase {
@Override
@@ -30,5 +40,16 @@ public class SaajSoap11MessageFactoryTest extends AbstractSoap11MessageFactoryTe
return new SaajSoapMessageFactory(messageFactory);
}
+ @Test
+ public void properties() throws IOException {
+ Map properties = Collections.singletonMap(SOAPMessage.WRITE_XML_DECLARATION, "true");
+ ((SaajSoapMessageFactory)messageFactory).setMessageProperties(properties);
+ SoapMessage soapMessage = (SoapMessage) messageFactory.createWebServiceMessage();
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ soapMessage.writeTo(os);
+ String result = os.toString("UTF-8");
+ assertTrue("XML declaration not written", result.startsWith("