0

Java web-app には完了に時間がかかるタスクがあり、タスクが完了する前にリクエストがタイムアウトし、ページが表示されません。リクエストを適切なアクション クラスにリダイレクトするフロント コントローラとして機能する非同期リダイレクト サーブレットを設定することを考えています。リクエストが処理されている間、対応するアクション クラスによってリクエストが完了するまで、サーブレットは約 1 分ごとにハートビートを送信し続けます。アクション クラス。非同期サーブレット 3.0 を使用して同様のものを実装した人はいますか? また、これは可能ですか?これはサーバープッシュに似ていることを理解しています。ご指導ありがとうございます。

4

1 に答える 1

1

はい、この種の機能は、非同期サーブレット 3.0 を使用して達成できます。基本的にはプッシュ通知のように機能し、ここで要求を行わなくても継続的に応答できます。このコードと共有するコードが 1 つあります。非同期要求を行うのに役立つ場合があります。 .

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";
    }
于 2014-05-31T09:24:53.013 に答える