6.3. Large Attachments

JAX-WS RI provides support for sending and receiving large attachments in a streaming fashion. Often times, large attachments need to be stored on the file system since they cannot be kept in memory(limited by heap size). But in certain cases, streaming of attachments is possible without ever storing the content on the file system. RI will try to stream the attachments whenever it is possible. Otherwise, it would store the large attachments on the file system.

The programming model is based on MTOM and DataHandler. You want to send large data as a SOAP attachment, see this section for more details. Also you want to bind large data to DataHandler instead of byte[]. RI provides a StreamingDataHandler, a DataHandler implementation that can be used to access the data efficiently in a streaming fashion.

6.3.1. Client Side

RI uses Java SE's HttpURLConnection for web service invocations. HttpURLConnection buffers the request data by default. So the client applications need to enable streaming explicitly, see http client streaming. The following sample show how to send and receive large data.

Sample client for large attachments

import com.sun.xml.ws.developer.JAXWSProperties;
import com.sun.xml.ws.developer.StreamingDataHandler;

MTOMFeature feature = new MTOMFeature();
MyService service = new MyService();
MyProxy proxy = service.getProxyPort(feature);
Map<String, Object> ctxt = ((BindingProvider)proxy).getRequestContext();
// Enable HTTP chunking mode, otherwise HttpURLConnection buffers
ctxt.put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192); 
DataHandler dh = proxy.fileUpload(...);
StreamingDataHandler sdh = (StreamingDataHandler)dh;
InputStream in = sdh.readOnce();
...
in.close();
sdh.close();
      

6.3.2. Server Side

Use @MTOM feature for a service and DataHandler parameter for large data. If the WSDL contains xmime:expectedContentTypes="application/octet-stream", it would be mapped to DataHandler in the generated SEI. If the service is starting from java, @XmlMimeType("application/octet-stream") can be used to generate an appropriate schema type in the generated WSDL.

The following sample shows how to upload files. It uses StreamingDataHandler.moveTo(File) convenient method to store the contents of the attachment to a file.

Sample service for large attachments

import com.sun.xml.ws.developer.StreamingDataHandler;
...

@MTOM
@WebService
public class UploadImpl {

    // Use @XmlMimeType to map to DataHandler on the client side
    public void fileUpload(String name, @XmlMimeType("application/octet-stream") DataHandler data) {
        try {
             StreamingDataHandler dh = (StreamingDataHandler)data;
             File file = File.createTempFile(name, "");
             dh.moveTo(file);
             dh.close();
        } catch(Exception e) {
             throw new WebServiceException(e);
        }
    }
}
      

6.3.3. Configuration

You can configure streaming attachments behaviour using @StreamingAttachment on the server side, and using StreamingAttachmentFeature on the client side. Using this feature, you can configure only certain sized attachments are written to a file.
Sample Service Configuration

import com.sun.xml.ws.developer.StreamingAttachment;

// Configure such that whole MIME message is parsed eagerly,
// Attachments under 4MB are kept in memory
@MTOM
@StreamingAttachment(parseEagerly=true, memoryThreshold=4000000L)
@WebService
public class UploadImpl {
}
      
Sample client configuration

import com.sun.xml.ws.developer.StreamingAttachmentFeature;

MTOMFeature mtom = new MTOMFeature();
// Configure such that whole MIME message is parsed eagerly,
// Attachments under 4MB are kept in memory
StreamingAttachmentFeature stf = new StreamingAttachmentFeature(null, true, 4000000L);
MyService service = new MyService();
MyProxy proxy = service.getProxyPort(feature, stf);
      

6.3.4. Large Attachments Summary

  • Use MTOM and DataHandler in the programming model.
  • Cast the DataHandler to StreamingDataHandler and use its methods.
  • Make sure you call StreamingDataHandler.close() and also close the StreamingDataHandler.readOnce() stream.
  • Enable HTTP chunking on the client-side.

Terms of Use; Privacy Policy; Copyright ©2013-2014 (revision 20140418.2d69abc)
 
 
Close
loading
Please Confirm
Close