Note that there are some explanatory texts on larger screens.

plurals
  1. POBuilding large MTOM/XOP messages with JAX-WS
    primarykey
    data
    text
    <p>I have a question about using MTOM/XOP with JAX-WS. I'm writing a web service which sends large amounts of binary data. The client requests a number of files and the server returns the files in the response.</p> <p>I'm able to get it to build the response correctly so that it correctly implements XOP, but I run into memory-related issues becasuse it stores the <strong>entire</strong> response in memory before sending it. The files this web service sends can get <strong>very</strong> large (like, giga-bytes large), so storing the response in memory is not an option.</p> <p><a href="http://download.oracle.com/docs/cd/E12840_01/wls/docs103/webserv_adv/mtom.html#wp279644" rel="noreferrer">This Oracle website</a> (and along with <a href="https://metro.dev.java.net/guide/Large_Attachments.html" rel="noreferrer">this one</a>) seems to solve this problem, but I just don't understand it. I think they use a <code>DataHandler</code> object to stream the request/response, but I can't figure out how they instantiate it.</p> <p>I'm generating my JAX-WS class files from an existing WSDL using <code>wsimport</code>. I'm using JAX-WS RI 2.1.6 with Java 6.</p> <p><em>How do I send the response as I'm building it without having to store in all in memory first?</em></p> <p>Thanks in advance for your help.</p> <hr> <p><strong>UPDATE 12/17:</strong> I added the following attributes to the schema element in the WSDL that holds the binary data. This causes <code>wsimport</code> to add a <code>DataHandler</code> object to the JAXB class. A <code>FileDataHandler</code> can then be added to the response, instead of adding the entire contents of the file, allowing the server to stream the contents of each file, instead of holding them all in memory:</p> <pre><code>xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmime:expectedContentTypes="application/octet-stream" </code></pre> <p>So, the server correctly builds the response now, and client properly saves each file to disk when it receives the request. However, the client still reads the entire response into memory for some reason.</p> <hr> <p><strong>The server code (SIB):</strong></p> <pre><code>@MTOM @StreamingAttachment(parseEagerly = true, memoryThreshold = 4000000L) @WebService(...) public class DownloadFilesPortTypeImpl implements DownloadFilesPortType { @Override public FileSetResponseType downloadFileSet(FileSetRequestType body) { FileSetResponseType response = new FileSetResponseType(); for (FileRequest freq : body.getFileRequest()){ try{ //find the file on disk File file = findFile(freq.getFileId()); //read the file data into memory byte[] fileData; { FileInputStream in = new FileInputStream(file); ByteArrayOutputStream out = new ByteArrayOutputStream(); byte buf[] = new byte[8192]; int read; while ((read = in.read(buf)) != -1){ out.write(buf, 0, read); } in.close(); out.close(); fileData = out.toByteArray(); } //add the file to the response FileResponse fresp = new FileResponse(); fresp.setFileId(freq.getFileId()); fresp.setData(fileData); //&lt;-- type "xs:base64Binary" response.getFileResponse().add(fresp); } catch (IOException e){ } } return response; } } </code></pre> <p><strong>The client code:</strong></p> <pre><code>DownloadFilesService service = new DownloadFilesService(); MTOMFeature mtomFeature = new MTOMFeature(); StreamingAttachmentFeature stf = new StreamingAttachmentFeature(null, true, 4000000L); DownloadFilesPortType port = service.getDownloadFilesPortSoap12(mtomFeature, stf); FileSetRequestType request = new FileSetRequestType(); FileRequest freq = new FileRequest(); freq.setFileId("1234"); request.getFileRequest().add(freq); freq = new FileRequest(); freq.setFileId("9876"); request.getFileRequest().add(freq); //... FileSetResponseType response = port.downloadFileSet(request); //reads entire response into memory for (FileResponse fres : response.getFileResponse()){ byte[] data = fres.getFileData(); //... } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload