SWS-246
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.ws.soap.axiom;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
@@ -36,11 +37,17 @@ import org.apache.axiom.soap.impl.llom.soap11.SOAP11Factory;
|
||||
import org.apache.axiom.soap.impl.llom.soap12.SOAP12Factory;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
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;
|
||||
import org.springframework.ws.soap.SoapVersion;
|
||||
import org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor;
|
||||
import org.springframework.ws.soap.server.endpoint.mapping.SoapActionEndpointMapping;
|
||||
import org.springframework.ws.transport.TransportConstants;
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
|
||||
@@ -48,13 +55,18 @@ import org.springframework.ws.transport.TransportInputStream;
|
||||
* Axiom-specific implementation of the {@link org.springframework.ws.WebServiceMessageFactory WebServiceMessageFactory}
|
||||
* interface. Creates {@link org.springframework.ws.soap.axiom.AxiomSoapMessage AxiomSoapMessages}.
|
||||
* <p/>
|
||||
* To increase reading performance on the the SOAP request created by this message context factory, you can set the
|
||||
* <code>payloadCaching</code> property to <code>false</code> (default is <code>true</code>). This this will read the
|
||||
* contents of the body directly from the stream. However, <strong>when this setting is enabled, the payload can only be
|
||||
* read once</strong>. This means that any endpoint mappings or interceptors which are based on the message payload
|
||||
* (such as the <code>PayloadRootQNameEndpointMapping</code>, the <code>PayloadValidatingInterceptor</code>, or the
|
||||
* <code>PayloadLoggingInterceptor</code>) cannot be used. Instead, use an endpoint mapping that does not consume the
|
||||
* payload (i.e. the <code>SoapActionEndpointMapping</code>).
|
||||
* To increase reading performance on the the SOAP request created by this message factory, you can set the {@link
|
||||
* #setPayloadCaching(boolean) payloadCaching} property to <code>false</code> (default is <code>true</code>). This this
|
||||
* will read the contents of the body directly from the stream. However, <strong>when this setting is enabled, the
|
||||
* payload can only be read once</strong>. This means that any endpoint mappings or interceptors which are based on the
|
||||
* message payload (such as the {@link PayloadRootQNameEndpointMapping}, the {@link PayloadValidatingInterceptor}, or
|
||||
* the {@link PayloadLoggingInterceptor}) cannot be used. Instead, use an endpoint mapping that does not consume the
|
||||
* payload (i.e. the {@link SoapActionEndpointMapping}).
|
||||
* <p/>
|
||||
* Additionally, this message factory can cache large attachments to disk by setting the {@link
|
||||
* #setAttachmentCaching(boolean) attachmentCaching} property to <code>true</code> (default is <code>false</code>).
|
||||
* Optionally, the location where attachments are stored can be defined via the {@link #setAttachmentCacheDir(File)
|
||||
* attachmentCacheDir} property (defaults to the system temp file path).
|
||||
* <p/>
|
||||
* Mostly derived from <code>org.apache.axis2.transport.http.HTTPTransportUtils</code> and
|
||||
* <code>org.apache.axis2.transport.TransportUtils</code>, which we cannot use since they are not part of the Axiom
|
||||
@@ -79,6 +91,12 @@ public class AxiomSoapMessageFactory implements SoapMessageFactory, Initializing
|
||||
|
||||
private boolean payloadCaching = true;
|
||||
|
||||
private boolean attachmentCaching = false;
|
||||
|
||||
private File attachmentCacheDir;
|
||||
|
||||
private int attachmentCacheThreshold = 4096;
|
||||
|
||||
// use SOAP 1.1 by default
|
||||
private SOAPFactory soapFactory = new SOAP11Factory();
|
||||
|
||||
@@ -88,14 +106,51 @@ public class AxiomSoapMessageFactory implements SoapMessageFactory, Initializing
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the SOAP Body payload should be cached or not. Default is <code>true</code>. Setting this to
|
||||
* <code>false</code> will increase performance, but also result in the fact that the message payload can only be
|
||||
* read once.
|
||||
* Indicates whether the SOAP Body payload should be cached or not. Default is <code>true</code>.
|
||||
* <p/>
|
||||
* Setting this to <code>false</code> will increase performance, but also result in the fact that the message
|
||||
* payload can only be read once.
|
||||
*/
|
||||
public void setPayloadCaching(boolean payloadCaching) {
|
||||
this.payloadCaching = payloadCaching;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether SOAP attachments should be cached or not. Default is <code>false</code>.
|
||||
* <p/>
|
||||
* Setting this to <code>true</code> will cause Axiom to store larger attachments on disk, rather than in memory.
|
||||
* This decreases memory consumption, but decreases performance.
|
||||
*/
|
||||
public void setAttachmentCaching(boolean attachmentCaching) {
|
||||
this.attachmentCaching = attachmentCaching;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the directory where SOAP attachments will be stored. Only used when {@link #setAttachmentCaching(boolean)
|
||||
* attachmentCaching} is set to <code>true</code>.
|
||||
* <p/>
|
||||
* The parameter should be an existing, writable directory. This property defaults to the temporary directory of the
|
||||
* operating system (i.e. the value of the <code>java.io.tmpdir</code> system property).
|
||||
*/
|
||||
public void setAttachmentCacheDir(File attachmentCacheDir) {
|
||||
Assert.notNull(attachmentCacheDir, "'attachmentCacheDir' must not be null");
|
||||
Assert.isTrue(attachmentCacheDir.isDirectory(), "'attachmentCacheDir' must be a directory");
|
||||
Assert.isTrue(attachmentCacheDir.canWrite(), "'attachmentCacheDir' must be writable");
|
||||
this.attachmentCacheDir = attachmentCacheDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the threshold for attachments caching, in bytes. Attachments larger than this threshold will be cached in
|
||||
* the {@link #setAttachmentCacheDir(File) attachment cache directory}. Only used when {@link
|
||||
* #setAttachmentCaching(boolean) attachmentCaching} is set to <code>true</code>.
|
||||
* <p/>
|
||||
* Defaults to 4096 bytes (i.e. 4 kilobytes).
|
||||
*/
|
||||
public void setAttachmentCacheThreshold(int attachmentCacheThreshold) {
|
||||
Assert.isTrue(attachmentCacheThreshold > 0, "'attachmentCacheThreshold' must be larger than 0");
|
||||
this.attachmentCacheThreshold = attachmentCacheThreshold;
|
||||
}
|
||||
|
||||
public void setSoapVersion(SoapVersion version) {
|
||||
if (SoapVersion.SOAP_11 == version) {
|
||||
soapFactory = new SOAP11Factory();
|
||||
@@ -113,6 +168,10 @@ public class AxiomSoapMessageFactory implements SoapMessageFactory, Initializing
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(payloadCaching ? "Enabled payload caching" : "Disabled payload caching");
|
||||
}
|
||||
if (attachmentCacheDir == null) {
|
||||
String tempDir = System.getProperty("java.io.tmpdir");
|
||||
setAttachmentCacheDir(new File(tempDir));
|
||||
}
|
||||
}
|
||||
|
||||
public WebServiceMessage createWebServiceMessage() {
|
||||
@@ -172,7 +231,8 @@ public class AxiomSoapMessageFactory implements SoapMessageFactory, Initializing
|
||||
private AxiomSoapMessage createMultiPartAxiomSoapMessage(InputStream inputStream,
|
||||
String contentType,
|
||||
String soapAction) throws XMLStreamException {
|
||||
Attachments attachments = new Attachments(inputStream, contentType);
|
||||
Attachments attachments = new Attachments(inputStream, contentType, attachmentCaching,
|
||||
attachmentCacheDir.getAbsolutePath(), Integer.toString(attachmentCacheThreshold));
|
||||
XMLStreamReader reader = inputFactory.createXMLStreamReader(attachments.getSOAPPartInputStream(),
|
||||
getCharSetEncoding(attachments.getSOAPPartContentType()));
|
||||
StAXSOAPModelBuilder builder;
|
||||
|
||||
@@ -27,31 +27,4 @@ public class AxiomSoap11MessageFactoryTest extends AbstractSoap11MessageFactoryT
|
||||
return factory;
|
||||
}
|
||||
|
||||
/*
|
||||
public void testCreateMtom() throws Exception {
|
||||
SOAP11Factory factory = new SOAP11Factory();
|
||||
SOAPEnvelope envelope = factory.getDefaultEnvelope();
|
||||
|
||||
OMNamespace namespace = factory.createOMNamespace("http://springframework.org/spring-ws/mtom", "sws");
|
||||
OMElement element = factory.createOMElement("image", namespace);
|
||||
envelope.getBody().addChild(element);
|
||||
DataHandler dataHandler = new javax.activation.DataHandler(new FileDataSource("/Users/arjen/spring-ws/src/site/resources/images/spring-ws.png"));
|
||||
|
||||
//create an OMText node with the above DataHandler and set optimized to true
|
||||
OMText textData = factory.createOMText(dataHandler, true);
|
||||
|
||||
element.addChild(textData);
|
||||
|
||||
OMOutputFormat format = new OMOutputFormat();
|
||||
format.setDoOptimize(true);
|
||||
format.setSOAP11(true);
|
||||
format.setCharSetEncoding("UTF-8");
|
||||
assertTrue(format.isOptimized());
|
||||
OutputStream os = new BufferedOutputStream(new FileOutputStream(
|
||||
"/Users/arjen/Projects/Spring/spring-ws/core/src/test/resources/org/springframework/ws/soap/soap11/soap11-mtom.bin"));
|
||||
try {
|
||||
envelope.serialize(os, format);
|
||||
} finally {
|
||||
os.close();
|
||||
*/
|
||||
}
|
||||
Reference in New Issue
Block a user