Skip to main content

MTOM best practices

1 reply [Last post]
csergiu77
Offline
Joined: 2005-02-06
Points: 0

I use Weblogic 10.3.2 ( so jaxws metro based )

The web app I have is uploading and downloading large files (PDF's) via a WS (i know is not the optimum way for doing this but this is how it is now)

NOW the files that are uploaded and downloaded are inside the payload (base64).

10 simultaneously users can cause easily OOME , with some large payloads.

So for download operation I would like to stream the the pdf from the database to the user

For this I changed the WS in order to use MTOM :

@Mtom+ changed the wsdl

minOccurs="0" xmime:expectedContentTypes="*/*"

xmlns:xmime="http://www.w3.org/2005/05/xmlmime" />

The ws returned this time DataHandler and I instantiated

return new DataHandler(new InputStreamDataSource(null, "*/*", inputStreamFromOracleBlob));

Code for InputStreamDataSource http://tny.cz/7122db2b

After I generate the client I use

DataHandler dh = port.download(id);

StreamingDataHandler sdh = (StreamingDataHandler)dh;

InputStream in = sdh.readOnce();

FileOutputStream fos = new FileOutputStream(new File("c://test.pdf"));

org.apache.xmlbeans.impl.common.IOUtil.copyCompletely(in, fos);

So things look ok….

What I fear is that I am mot applying the best practices and I am stuck a little bit with upload.

On upload I do not know how can I stream the content to the server and then into DB. (maybe I should create OutputStreamDataSource ?)

Any idea for upload ?

Should I use better the already done ByteArrayDataSource ? not the custom InputStreamDataSource ?

Do I have to use @StreamingAttachment(parseEagerly=true, memoryThreshold=4000000L)?

What if I don’t use @StreamingAttachment on WS , it will not use streaming ?
Thanks a lot.
Cris

PS.
I took a look on InputStreamDataSource and javax.mail.util.ByteArrayDataSourceand i realized that they acutal hava a byte[] of the 'document' in memory meaning the streaming ideea is in vain, cause what i try to avoid is to have multiple docs in the same time fully in memory.

So how can I stream from DB via WS and MTOM to a WS client ?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
csergiu77
Offline
Joined: 2005-02-06
Points: 0

I tried experimenting and finally i had some positive results.
In order to stream from DB directly to clients browser the above things are valid but the InputStreamDataSource should be like this:

public class InputStreamDataSource implements DataSource {
private InputStream inputStream;

public InputStreamDataSource(InputStream inputStream) {
this.inputStream = inputStream;
}

public InputStream getInputStream() throws IOException {
return inputStream;
}

public OutputStream getOutputStream() throws IOException {
throw new UnsupportedOperationException("Not implemented");
}

public String getContentType() {
return "*/*";
}

public String getName() {
return "InputStreamDataSource";
}
}

What I was affraid is that once I closed the input stream myself...the ws client did not received the binary content...

Than i check and actually the DataHandler creates a new thread and closes the input stream

I was able to stream 500MB from DB to client fast and with low memory footprint !