Java streaming

I have a servlet mapped to a url that does a long task and outputs some data while running.

What I want to do is call this url and see the output in real time.

Let's take this as an example:

package com.tasks;

public class LongTaskWithOutput extends HttpServlet {
    private static final long serialVersionUID = 2945022862538743411L;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.addHeader("Content-Type", "text/plain");
        PrintStream out = new PrintStream(response.getOutputStream(), true);

        for(int i=0; i<10;i++) {
            out.println("# " + i);
            out.flush();
            try {
                Thread.sleep(1000);
            } catch(Exception e){}
        }
    }

}

      

The web.xml

following is stated:

...
<servlet>
    <servlet-name>LongTaskServlet</servlet-name>
    <servlet-class>com.tasks.LongTaskWithOutput</servlet-class>
    <description>Long Task Servlet</description>
</servlet>
<servlet-mapping>
    <servlet-name>LongTaskServlet</servlet-name>
    <url-pattern>/longTask</url-pattern>
</servlet-mapping>
...

      

What's happening

If I browse localhost/myApp/longTask

, the browser makes me wait 10 seconds and then prints out all the text at once.

What is going to happen

The text should be sent to the browser as soon as it is written to the output stream, and the browser should render one line every second.

As you can see, I've already put out.flush()

in to make sure the thread is flushing every second, but it still doesn't work.

I also tried with response.flushBuffer()

, but I got the same result.

Is there a way to achieve this?


Update

As @MadConan suggested , I tried to use the output stream directly:

OutputStream out = response.getOutputStream();

for(int i=0; i<10;i++) {
    out.write(("# " + i + "\n").getBytes());
    out.flush();
    try {
        Thread.sleep(1000);
    } catch(Exception e){}
}

      

Unfortunately, the result is the same.

+3


source to share


2 answers


This is an upstream issue. The browser will not necessarily display this data as it receives it. It can wait for the request to complete. You may have an extra snippet if you are going through a proxy. If you peer into network traffic, I'm sure it will go as expected.



0


source


You are clearing the content from the response stream, but your response is not communicated to the client. Understand it this way: you give some things to be someone, take and leave the room and pass on to someone else. Until the person leaves the room and hands it in, your package will not be delivered.

For your requirement, you can keep pushing the data to some kind of global space and then have a PULL mechanism from the client to read that space every X seconds and display the content to the client. It is also possible for the PUSH mechanism to do the same, it depends on your project whether you should use PUSH or PULL.



This basically means that in one request you cannot update the client and go back to the server and do the same over and over. The request dies after the response has been sent to the client. Then there should be another PULL request from the client or PUSH from the server.

0


source







All Articles