users@jersey.java.net

[Jersey] Re: Unable to get ChunkedOutput to work properly using Tomcat 7

From: Marek Potociar <marek.potociar_at_oracle.com>
Date: Fri, 11 Oct 2013 23:51:54 +0200

On Oct 11, 2013, at 4:13 PM, Chun Tat David Chu <beyonddc.storage_at_gmail.com> wrote:

> Hi Marek,
>
> My test code on ChunkedOuput is not much different than the one in the tutorial. It does write the chunk in a separate thread.
> It spawns a new thread, sits in a loop and return 20 JSON objects. I used the CountDownLatch just to make sure that the thread doesn't begin until the method returned (see below).

>
> @PUT
> @Path("/asynchronous")
> @Produces(MediaType.APPLICATION_JSON)
> @Consumes(MediaType.APPLICATION_JSON)
> public ChunkedOutput<Person> getAsyncResponse(Person rep) {
>
> System.out.println("Received: " + rep);
>
> final CountDownLatch countDownLatch1 = new CountDownLatch(1);
>
> final ChunkedOutput<Person> output = new ChunkedOutput<Person>(String.class);
>
> new Thread() {
> public void run() {
> try {
>
> countDownLatch1.await();
> Thread.sleep(2000);
>
> for (int i = 0; i < 20; i++) {
>
> Person person = new Person("David",String.valueOf(i));
> output.write(person);
> Thread.sleep(1000);
> }
> } catch (Throwable th) {
> th.printStackTrace();
> } finally {
> try {
> output.close();
> } catch (IOException e) {
> // TODO Auto-generated catch block
> e.printStackTrace();
> }
> }
> }
> }.start();
>
> countDownLatch1.countDown();
>
> return output;
> }
>
> My test client side is also very simple. Followed the tutorial and it looks like this.
> ClientConfig clientConfig = new ClientConfig();
>
> Client client = ClientBuilder.newClient();
>
> final Response response = client.target("http://localhost:9080/jaxrs.prototype.tomcat7/rest/async/asynchronous").request(MediaType.APPLICATION_JSON).get();
>
>
> final ChunkedInput<String> chunkedInput =
> response.readEntity(new GenericType<ChunkedInput<String>>() {});
>

I think the problem is here - you need to set ChunkedInput parser (via setParser(...)) to tell the chunk input where each chunk starts. For simple cases you can try to use ChunkInput.createParser(...) methods to create a fixed boundary delimiter parser. For anything more complex you may need to implement a ChunkParser yourself.

Marek

> String chunk = null;
> chunk = chunkedInput.read();
> while (chunk != null) {
> System.out.println("Next chunk received: " + chunk);
> chunk = chunkedInput.read();
> }
>
> I am just not sure why it is not receiving a chunk at a time until all the chunk is received then it print all 20 JSON objects at once.
>
> Thanks,
>
> David
>
> On Fri, Oct 11, 2013 at 4:43 AM, Marek Potociar <marek.potociar_at_oracle.com> wrote:
>
> On Oct 9, 2013, at 6:58 AM, Chun Tat David Chu <beyonddc.storage_at_gmail.com> wrote:
>
>> Hi All,
>>
>> I am trying to get ChunkedOutput to work using Tomcat 7. My test code is very similar to what's available on the tutorial website. https://jersey.java.net/documentation/latest/async.html#chunked-output
>
> What is the difference between your code and the tutorial?
>
>>
>> I tried with both command line curl and a Java application that follows ChunkedInput tutorial https://jersey.java.net/documentation/latest/async.html#d0e7470
>>
>> By observing the behavior, it appears to me that my Java application is not receiving the chunked output whenever my web service is invoking chunkedOutput.write(). Instead all the chunked output is received at once after all the write is completed.
>
> It appears to me as though you are not using a separate thread to write the chunked data and trying to write all the chunks BEFORE you return your chunked output. Is that the case?
>
> In order order to receive new chunks immediately, you must first return the chunked output from your method and only then start writing new chunks.
>
> Marek
>
>>
>> Any one tried using ChunkedOutput with Tomcat 7? Is there anything that I must configure? or I need to use a different web server?
>>
>> Thanks!
>>
>> David
>>
>
>