Java 重定向servlet异步和心跳

Java 重定向servlet异步和心跳,java,web-applications,servlet-3.0,server-push,Java,Web Applications,Servlet 3.0,Server Push,java web app中的任务需要很长时间才能完成,在任务完成之前,请求超时,页面无法显示。我们正在考虑设置一个异步重定向servlet,该servlet充当前端控制器,将请求重定向到适当的操作类,并且当请求被服务时,servlet每隔一分钟左右发送一次心跳,直到相应的操作类完成请求。有人使用异步Servlet3.0实现过类似的功能吗?这也有可能吗?我知道这类似于服务器推送。谢谢您的指导。是的,您可以使用 异步servlet 3.0。它基本上像推送一样工作 通知,并不断给您回复 我在这里提出请

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

是的,您可以使用 异步servlet 3.0。它基本上像推送一样工作 通知,并不断给您回复 我在这里提出请求,我有一个代码与大家共享 此代码可能有助于您发出异步请求

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";
    }
此示例检查实时用户
@WebServlet(urlPatterns={“/checkliveuser”},asyncSupported=true)
公共类CheckLiveUser扩展HttpServlet{
私有静态最终长serialVersionUID=1L;
私有静态最终队列队列=新ConcurrentLinkedQueue();
private static final BlockingQueue messageQueue=new LinkedBlockingQueue();
私有静态最终字符串BEGIN\u SCRIPT\u TAG=“\n”;
私有静态最终字符串结束\u脚本\u标记=“\n”;
私有线程notifierThread=null;
@凌驾
public void init(ServletConfig config)抛出ServletException{
ServletContext=config.getServletContext();
Set users=new HashSet();
映射页面=新的HashMap();
setAttribute(“页面”,第页);
setAttribute(“messageQueue”,messageQueue);
Runnable notifierRunnable=新的Runnable(){
公开募捐{
布尔完成=假;
而(!完成){
System.out.println(“线程内”);
字符串cMessage=null;
试一试{
cMessage=BEGIN\u SCRIPT\u TAG+toJsonp(“实时用户:”,messageQueue.take())
+结束\脚本\标记;
for(异步上下文ac:队列){
试一试{
PrintWriter acWriter=ac.getResponse()
.getWriter();
acWriter.println(cMessage);
acWriter.flush();
}捕获(IOEX异常){
系统输出打印项次(ex);
队列。移除(ac);
}
}
}捕获(中断异常iex){
完成=正确;
系统输出打印项次(iex);
}
}
}
};
notifierThread=新线程(notifierRunnable);
notifierThread.start();
}
/**
*@参见HttpServlet#doGet(HttpServletRequest请求,HttpServletResponse
*(答复)
*/
受保护的无效数据集(HttpServletRequest请求,
HttpServletResponse响应)引发ServletException,IOException{
response.setContentType(“text/html”);
PrintWriter=response.getWriter();
setAttribute(“org.apache.catalina.ASYNC_-SUPPORTED”,true);
final AsyncContext ac=request.startAsync();
ac.setTimeout(10*60*1000*1000);
ac.addListener(新的AsyncListener(){
public void onComplete(AsyncEvent事件)引发IOException{
队列。移除(ac);
System.out.println(“完成时”);
}
public void onTimeout(AsyncEvent事件)引发IOException{
队列。移除(ac);
System.out.println(“超时时”);
}
public void onError(AsyncEvent事件)引发IOException{
队列。移除(ac);
System.out.println(“错误时”);
}
公共void onStartAsync(AsyncEvent事件)引发IOException{
System.out.println(“启动时”);
}
});
队列。添加(ac);
}
/**
*@参见HttpServlet#doPost(HttpServletRequest,HttpServletResponse
*(答复)
*/
受保护的void doPost(HttpServletRequest请求,
HttpServletResponse响应)引发ServletException,IOException{
response.setContentType(“文本/普通”);
响应。setCharacterEncoding(“UTF-8”);
ServletContext=request.getServletContext();
HttpSession session=request.getSession();
映射登录=(映射)上下文
.getAttribute(“页面”);
if(request.getParameter(“操作”)!=null
&&!request.getParameter(“操作”).isEmpty(){
if(request.getParameter(“action”).equalsIgnoreCase(“注销”)){
删除(request.getSession().getId());
request.getSession().invalidate();
}
}
字符串名称=request.getParameter(“loginID”);
if(name!=null){
session.setAttribute(“用户”,名称);
session.setAttribute(“jsessionId”,session.getId());
logins.put(session.getId(),name);
}
字符串html=“”;
对于(Map.Entry:logins.entrySet()){
System.out.println(“键:”+entry.getKey()+“值:”
+entry.getValue());
html+=entry.getValue()+“
”; } 字符串cMessage=BEGIN\u SCRIPT\u TAG+toJsonp(“实时用户:”,html) +结束\脚本\标记; 通知(cMessage); response.getWriter().println(“成功”); if(request.getParameter(“操作”)!=null &&!request.getParameter(“操作”).isEmpty(){ if(request.getParam)