重定向servlet异步和心跳

时间:2013-09-02 04:27:14

标签: java web-applications servlet-3.0 server-push

我们在java web-app中有任务需要很长时间才能完成,在任务完成请求超时之前,页面无法显示。我们考虑设置一个异步重定向servlet作为前端控制器将请求重定向到适当的操作类,并且在请求被提供时,servlet每隔一分钟左右发送一次心跳,直到相应的请求完成为止。行动班。有没有人使用异步servlet 3.0实现类似的东西?这也可能吗?我知道这与服务器推送类似。感谢您的指导。

1 个答案:

答案 0 :(得分:1)

是的这种功能你可以通过使用来实现 异步servlet 3.0.it基本上像push一样工作 通知,并让你不断安息 在这里提出请求我有一个代码,我分享 此代码可能有助于您进行异步请求。

this example check live users



@WebServlet(urlPatterns = { "/checkliveuser" }, asyncSupported = true)
public class CheckLiveUser extends HttpServlet {
    private static final long serialVersionUID = 1L;

    private static final Queue<AsyncContext> queue = new ConcurrentLinkedQueue();

    private static final BlockingQueue<String> messageQueue = new LinkedBlockingQueue();

    private static final String BEGIN_SCRIPT_TAG = "<script type='text/javascript'>\n";

    private static final String END_SCRIPT_TAG = "</script>\n";

    private Thread notifierThread = null;
    @Override
    public void init(ServletConfig config) throws ServletException {

        ServletContext context = config.getServletContext();
        Set<String> users = new HashSet<String>();
        Map<String, String> page = new HashMap<String, String>();
        context.setAttribute("page", page);
        context.setAttribute("messageQueue", messageQueue);


        Runnable notifierRunnable = new Runnable() {
            public void run() {
                boolean done = false;
                while (!done) {
                    System.out.println("in thread");
                    String cMessage = null;
                    try {
                        cMessage = BEGIN_SCRIPT_TAG + toJsonp("<b>Live User:", messageQueue.take())
                        + END_SCRIPT_TAG;
                        for (AsyncContext ac : queue) {
                            try {
                                PrintWriter acWriter = ac.getResponse()
                                        .getWriter();
                                acWriter.println(cMessage);
                                acWriter.flush();
                            } catch (IOException ex) {
                                System.out.println(ex);
                                queue.remove(ac);

                            }
                        }
                    } catch (InterruptedException iex) {
                        done = true;
                        System.out.println(iex);
                    }
                }
            }
        };
        notifierThread = new Thread(notifierRunnable);
        notifierThread.start();
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {


        response.setContentType("text/html");

        PrintWriter writer = response.getWriter();

request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true);
        final AsyncContext ac = request.startAsync();
        ac.setTimeout(10 * 60 * 1000 * 1000);
        ac.addListener(new AsyncListener() {
            public void onComplete(AsyncEvent event) throws IOException {
                queue.remove(ac);
                System.out.println("on complete");
            }

            public void onTimeout(AsyncEvent event) throws IOException {
                queue.remove(ac);
                System.out.println("on timeout");
            }

            public void onError(AsyncEvent event) throws IOException {
                queue.remove(ac);
                System.out.println("on error");

            }

            public void onStartAsync(AsyncEvent event) throws IOException {
                System.out.println("on startup");
            }
        });
        queue.add(ac);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        response.setContentType("text/plain");
        response.setCharacterEncoding("UTF-8");
        ServletContext context = request.getServletContext();
        HttpSession session = request.getSession();
        Map<String, String> logins = (Map<String, String>) context
                .getAttribute("page");
        if (request.getParameter("action") != null
                && !request.getParameter("action").isEmpty()) {

            if (request.getParameter("action").equalsIgnoreCase("logout")) {

                logins.remove(request.getSession().getId());
                request.getSession().invalidate();

            }
        }
        String name = request.getParameter("loginID");
        if (name != null) {

            session.setAttribute("user", name);
            session.setAttribute("jsessionId", session.getId());
            logins.put(session.getId(), name);

        }
        String html = "";

        for (Map.Entry<String, String> entry : logins.entrySet()) {
            System.out.println("Key : " + entry.getKey() + " Value : "
                    + entry.getValue());
            html += entry.getValue() + "<br>";
        }

        String cMessage = BEGIN_SCRIPT_TAG + toJsonp("<b>Live User:", html)
                + END_SCRIPT_TAG;
        notify(cMessage);

        response.getWriter().println("success");
        if (request.getParameter("action") != null
                && !request.getParameter("action").isEmpty()) {

            if (request.getParameter("action").equalsIgnoreCase("logout"))
                response.sendRedirect("login.jsp");

        } else {
            response.sendRedirect("welcome.jsp");
        }

    }

    @Override
    public void destroy() {
        queue.clear();
        notifierThread.interrupt();
    }

    private void notify(String cMessage) throws IOException {
        try {
            messageQueue.put(cMessage);
        } catch (Exception ex) {
            IOException t = new IOException();
            t.initCause(ex);
            throw t;
        }
    }

    private String escape(String orig) {
        StringBuffer buffer = new StringBuffer(orig.length());

        for (int i = 0; i < orig.length(); i++) {
            char c = orig.charAt(i);
            switch (c) {
            case '\b':
                buffer.append("\\b");
                break;
            case '\f':
                buffer.append("\\f");
                break;
            case '\n':
                buffer.append("<br />");
                break;
            case '\r':
                // ignore
                break;
            case '\t':
                buffer.append("\\t");
                break;
            case '\'':
                buffer.append("\\'");
                break;
            case '\"':
                buffer.append("\\\"");
                break;
            case '\\':
                buffer.append("\\\\");
                break;
            case '<':
                buffer.append("<");
                break;
            case '>':
                buffer.append(">");
                break;
            case '&':
                buffer.append("&");
                break;
            default:
                buffer.append(c);
            }
        }

        return buffer.toString();
    }

    private String toJsonp(String name, String message) {
        return "window.parent.app.update({ name: \"" + escape(name)
                + "\", message: \"" + escape(message) + "\" });\n";
    }