Streaming in jersey 2?
Your edit it correct. It is working as expected. Also StreamingOutput
is just a wrapper that let's us write directly to the response stream, but does not actually mean the response is streamed on each server side write to the stream.AsyncResponse
does not provide any different response as far as the client is concerned. It is simply to help increase throughput with long running tasks. The long running task should actually be done in another thread, so the method can return.
- See more at Asynchronous Server API
What you seem to be looking for instead is Chunked Output
Jersey offers a facility for sending response to the client in multiple more-or-less independent chunks using a chunked output. Each response chunk usually takes some (longer) time to prepare before sending it to the client. The most important fact about response chunks is that you want to send them to the client immediately as they become available without waiting for the remaining chunks to become available too.
Not sure how it will work for your particular use case, as the JsonGenerator
expects an OutputStream
(of which the ChuckedOutput
we use is not), but here is a simpler example
@Path("async")public class AsyncResource { @GET public ChunkedOutput<String> getChunkedStream() throws Exception { final ChunkedOutput<String> output = new ChunkedOutput<>(String.class); new Thread(() -> { try { String chunk = "Message"; for (int i = 0; i < 10; i++) { output.write(chunk + "#" + i); Thread.sleep(1000); } } catch (Exception e) { } finally { try { output.close(); } catch (IOException ex) { Logger.getLogger(AsyncResource.class.getName()) .log(Level.SEVERE, null, ex); } } }).start(); return output; }}
Note: I had a problem getting this to work at first. I would only get the delayed complete result. The problem seemed to have been with something completely separate from the program. It was actually my AVG causing the problem. Some feature called "LinkScanner" was stopping this chunking process to occur. I disabled that feature and it started working.
I haven't explored chunking much, and am not sure the security implications, so I am not sure why the AVG application has a problem with it.
EDIT
Seems the real problem is due to Jersey buffering the response in order to calculate the Content-Length header. You can see this post for how you can change this behavior