I have a SOAP web service based on Axis2 1.4.1 that accepts MTOM uploads using the pattern from the docs:
public class MTOMService {
public void uploadFileUsingMTOM(OMElement element) throws Exception {
OMText binaryNode = (OMText) (element.getFirstElement()).getFirstOMChild();
DataHandler actualDH;
actualDH = (DataHandler) binaryNode.getDataHandler();
// consume data from DataHandler
InputStream inputStream = actualDH.getInputStream();
}
}
I potentially need to read the data from the DataHandler more than once.
inputStream.close();
// get second InputStream to consume same data from DataHandler again
InputStream inputStream2 = actualDH.getInputStream();
This works in simple tests. Can I assume this is always safe?
PartOnFile
, spooled to disk from memory which supports re-use until (I think) the end of the SOAP request; read via FileAccessor
PartOnMemoryEnhanced
, which stores the data in multiple byte
arrays and so should support re-use until garbage collectedParserInputStreamDataSource
which supports different destructive or non-destructive Behavior
enums, but Axis trunk does not specify and so Axiom defaults to Behavior.NON_DESTRUCTIVE
which allows re-reads.but this is all from a cursory scan of the code, which I don't know every well, so I may have missed other code paths or I may just be wrong.
Does Axis, or any of the other interfaces here, guarantee that DataHandlers can be read more than once? If not, is there a good mechanism to detect when Axis is passing attachments read-once-only mode so I can cache the first read myself? Does it make a difference if the request is MTOM or not? Thanks!
The DataHandler#getInputStream()
method basically delegates to DataSource#getInputStream()
and the contract of that method specifically requires that the content of the DataSource
can be read multiple times. Axiom is designed to conform to that contract.
Axiom defines an extension interface (DataHandlerExt
) that can be used in scenarios where one wants to "destructively" read the content.
There is however one thing you need to pay attention to: at the end of the request processing (i.e. after your service has been invoked), Axis2 is expected to instruct Axiom to destroy the temporary files related to DataHandler
instances created during the request. That means that if you store a reference to a DataHandler
and try to access it later (in another request, or in some background thread), then this may fail. Note that in a future version of Axiom it is planned to introduce an option that would let the garbage collector handle that cleanup, which would avoid this problem.