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

Reply via email to