English 中文(简体)
AJAX (prototype/java) getting partial status updates during execution
原标题:

This partially mimics AJAX (prototype/php) getting partial status updates during script execution, however I m working with JSP pages and servlets. What I want to do is start an action when the user clicks a button and then present updates on the progress of this action. The action can take anywhere from 1 to 10 minutes to complete, so I don t want the user just sitting on the screen waiting for a response but rather display a status bar or something denoting what part of the action the transaction is on.

Thank you

最佳回答

If you want to run and control a long-running process, better let it run in its own Thread instead of the request s Thread. Store a reference to this Thread in the session scope so that the client can use ajaxical requests (using the same session!) to request the server side for the current progress (and automagically also to keep the session alive so that it doesn t timeout).

Here s a basic example of such a servlet:

package mypackage;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RunLongProcessServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
    {
        if ("XMLHttpRequest".equals(request.getHeader("x-requested-with"))) {
            LongProcess longProcess = (LongProcess) request.getSession().getAttribute("longProcess");
            response.setContentType("application/json");
            response.getWriter().write(String.valueOf(longProcess.getProgress()));
        } else {
            request.getRequestDispatcher("runLongProcess.jsp").forward(request, response);
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
    {
        LongProcess longProcess = new LongProcess();
        longProcess.setDaemon(true);
        longProcess.start();
        request.getSession().setAttribute("longProcess", longProcess);
        request.getRequestDispatcher("runLongProcess.jsp").forward(request, response);
    }

}

class LongProcess extends Thread {

    private int progress;

    public void run() {
        while (progress < 100) {
            try { sleep(1000); } catch (InterruptedException ignore) {}
            progress++;
        }
    }

    public int getProgress() {
        return progress;
    }

}

..which is mapped as follows:

<servlet>
    <servlet-name>runLongProcess</servlet-name>
    <servlet-class>mypackage.RunLongProcessServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>runLongProcess</servlet-name>
    <url-pattern>/runLongProcess</url-pattern>
</servlet-mapping>

And here s a basic example of the JSP (with a little shot jQuery, an ajaxical JS framework which I by the way greatly recommend):

<!doctype html>
<html lang="en">
    <head>
        <title>Show progress of long running process with help of Thread and Ajax.</title>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
        <script type="text/javascript">
            $(document).ready(init);

            function init() {
                if (${not empty longProcess}) {
                    $.progress = 0;
                    checkProgress();
                }
            }

            function checkProgress() {
                $.getJSON( runLongProcess , function(progress) {
                    $( #progress ).text(progress);
                    $.progress = parseInt(progress);
                });
                if ($.progress < 100) {
                    setTimeout(checkProgress, 1000);
                }
            }
        </script>
    </head>
    <body>
        <form action="runLongProcess" method="post">
            <p>Run long process: <input type="submit"></p>
            <p>Current status: <span id="progress">0</span>%</p>
        </form>
    </body>
</html>

Open it at http://localhost:8080/yourcontext/runLongProcess and click the button.

If this is a really, really long running process, you may improve "efficiency" by increasing the ajax request intervals in the setTimeout() to 5 seconds (5000 ms) or so, so that the server doesn t feel getting DDOS ed ;)

Hope this helps.

问题回答

You may like DWR. With help of DWR you could make async requests to the server to get information about the progress of the specific job.





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签