Hello,
I have a problem with streaming LOB data from a database via CXF+MTOM to a
client. It is not a
CXF-specific problem, but rather a conceptual problem.
I wrote an implementation of javax.activation.DataSource, which simply returns
an InputStream that
it has received via its constructor. The code in my service implementation
logic looks like this:
InputStream data = lobHandler.getBlobAsBinaryStream(resultSet, "data");
result.setData(new DataHandler(new StreamDataSource(data, fileName,
mimeType));
I think you get the idea: "data" is an InputStream which receives its data
directly from the
ResultSet. "StreamDataSource" uses this InputStream and passes it to the
activation framework. The
idea behind this code: Streaming directly from LOBs to the client.
In practice I am facing a problem: Right now, I am closing the ResultSet, the
Statement and the
Connection somewhere in my service implementation (shortly after the code I
have cited above).
However, CXF starts streaming only when I have left the implementation of the
service interface. CXF
tries to use this InputStream (which originates from the ResultSet) in its
outgoing chain in the
AttachmentOutInterceptor - *after* having executed the service implementation.
The consequence is,
that CXF cannot stream the data to the client, because the underlying
InputStream from the ResultSet
throws an exception, that the ResultSet has been closed already.
Do you have any suggestions for this problem?
One solution could be to stream the LOB data to a temporary file, close the
ResultSet and Statement
and return the InputStream of this file to CXF. Then, I would have to write a
servlet filter (or an
CXF interceptor) which would ultimately delete this temporary file. Tradeoff of
this solution:
performance penalty.
Another solution could be to close the ResultSet, Statement and Connection
after CXF has streamed
the data. Somewhere in a servlet filter or an CXF interceptor. But that would
mean that I would have
to stuff those three objects into "something" (ThreadLocal?) where they would
be protected from
garbage collection and accessible to the interceptor or filter. Not really
beautiful.
What do you think about this problem?
Thanks,
Martin