javacxfchunked-encoding

CXF buffering data when using chunked encoding


I've written a java REST (streaming) servlet using Apache CXF 2.5.1 and deployed it to a Tomcat 7.0.42 container. The REST endpoint is essentially an implementation of StreamingOutput, wrapped it a Response object that is handed off to the container when a client requests.

The nature of the service is to return a stream of sensor data to a client. This stream could theoretically be infinitely long because it's only terminated when the client disconnects. The issue arises when the data generated by the sensor comes in small quantities.

The service "works" but I'm running into an issue when it comes to the size of the data responses that the client receives. The client only receives data after an 8192 byte threshold has been broken by the service. Then the client receives 800 bytes, then 8192 bytes, then 800 bytes...

I would like the data to be sent to the client as soon as I invoke flush on the OutputStream which the container hands off to my implementation of StreamingOutput. However, the implementation of OutputStream that i'm given (WrappedOutputStream defined in org.apache.cxf.transport.http.AbstractHTTPDestination) has a flush method which does nothing.

Is there any way to have more control over the OutputStream that CXF uses so I can "flush" to the client on demand?


Solution

  • Ultimately the way I was able to flush the buffer on demand was to create a CXF filter, specifically an implementation of ResponseHandler.

    In the filter I grabbed the HttpServletResponse and the OutputStream implementation that CXF used (the one that wouldn't let me flush) from the Message implementation, wrapping them in a FilteredOutputStream. Whenever flush is invoked I explicitly invoke flush on the HttpServletResponse.

    This is specific to CXF and doing it this way can create a lot more overhead, depending on how often flush is invoked, but it does allow "slow" streaming to reach the client sooner.

    Please comment on any gotchas or things that I may need to be concerned about.