Javaservlet中的异步行为?

Javaservlet中的异步行为?,java,servlets,asynchronous,httprequest,httpresponse,Java,Servlets,Asynchronous,Httprequest,Httpresponse,我第一次尝试设计一个Javaservlet。 这是我的最终目标行为 Servlet接收一个请求 Servlet向另一台服务器发出HTTP请求(我们称之为MServer) MServer可以在接下来的20-25分钟内异步发送对我的servlet请求的回复 我想在servlet收到此数据后立即将此数据发送回用户(在步骤1中向servlet发出请求的用户) 你知道我该怎么做吗 到目前为止,我刚刚制作了一个“HelloWorld”Javaservlet。与MServer通信的代码也已准备就绪。但我不知道

我第一次尝试设计一个Javaservlet。 这是我的最终目标行为

  • Servlet接收一个请求
  • Servlet向另一台服务器发出HTTP请求(我们称之为MServer)
  • MServer可以在接下来的20-25分钟内异步发送对我的servlet请求的回复
  • 我想在servlet收到此数据后立即将此数据发送回用户(在步骤1中向servlet发出请求的用户) 你知道我该怎么做吗

    到目前为止,我刚刚制作了一个“HelloWorld”Javaservlet。与MServer通信的代码也已准备就绪。但我不知道如何实现这种异步行为


    任何帮助都将不胜感激

    您可能需要在客户端实现连续检查,在服务器端实现队列。换句话说,客户机将每隔1-2分钟与servlet联系一次,以检查发送给他的新消息。servlet还应该有一个异步获取数据的方法,然后将接收到的数据存储在队列中。可以通过多种方式实现这种队列,例如,通过将来自MServer的响应存储在数据库表中。

    下面是一个示例,希望对您有所帮助。它假设您有一个浏览器作为客户端,并实现jqueryajax调用。它每5秒检查一次来自Mserver的长时间运行调用是否完成,数据是否可供客户端使用。我希望它能帮助你:)

    您的servlet代码:

    public class TestServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String data = Mserver.getInstance().getData();
    
            response.setContentType("text/html;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
    
            PrintWriter out = response.getWriter();
            out.println(data);
        }
    }
    
    Mserver代码示例:

    public class Mserver {
        private String data;
        private static final Mserver mserver = new Mserver();
    
        public static Mserver getInstance() {
            return mserver;
        }
    
        private Mserver() {
            new Thread() {
                @Override
                public void run() {
                    computeData();
                }
            }.start();
        }
    
        // Computing data by making multiple server calls etc..
        private void computeData() {
            try {
                System.out.println("Waiting for 20 seconds simulating long running call");
                Thread.sleep(20000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            data = "Computed Data is ready now.";
        }
    
        public String getData() {
            return data;
        }
    }
    
    使用jQuery Ajax调用的Html页面:

    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script src="js/jquery.min.js"></script>
    <script type="text/javascript" charset="utf-8">
        $(document).ready(function() {
            setInterval(function() {
                $.ajax({
                    type:"get",
                    url: "checkDataFromMserver",
                    async: false,
                    success: function (data) {
                        $("#response").html(data);
                    }
                });
            }, 5000);
        });
    </script>
    </head>
    <body>
        Getting data using jQuery Ajax
        <div id="response"></div>
    </body>
    </html>
    
    
    $(文档).ready(函数(){
    setInterval(函数(){
    $.ajax({
    键入:“获取”,
    url:“checkDataFromMserver”,
    async:false,
    成功:功能(数据){
    $(“#响应”).html(数据);
    }
    });
    }, 5000);
    });
    使用jqueryajax获取数据
    
    我对它进行了测试,效果良好。客户端每5秒进行一次轮询,以检查数据是否准备就绪。20秒后,它从Mserver获取数据

    希望你觉得它有用

    我认为你应该使用一个。我假设有一个MServer facade如下所示:

    interface MServer {
        void getStuff(Observer observer);
    }
    
    interface Observer {
        void onNewStuff(String stuff);
        void onThatWasAllStuff();
    }
    
    class MServerSingleton {
        MServer getInstance() {
            // Code that returns an MServer.
        }
    }
    
    public class TheServlet extends HttpServlet {
        protected void doGet(HttpServletRequest req, final HttpServletResponse resp) {
            resp.setContentType("text/plain");
            final AsyncContext context = req.startAsync();
            MServerSingleton.getInstance().getStuff(new Observer() {
                void onNewStuff(String stuff) {
                    try {
                        resp.getWriter().write(stuff + "\n\n");
                        resp.getWriter().flush();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
    
                void onThatWasAllStuff() {
                    context.complete();
                }
            });
        }
    }
    
    然后,您可以实现如下servlet:

    interface MServer {
        void getStuff(Observer observer);
    }
    
    interface Observer {
        void onNewStuff(String stuff);
        void onThatWasAllStuff();
    }
    
    class MServerSingleton {
        MServer getInstance() {
            // Code that returns an MServer.
        }
    }
    
    public class TheServlet extends HttpServlet {
        protected void doGet(HttpServletRequest req, final HttpServletResponse resp) {
            resp.setContentType("text/plain");
            final AsyncContext context = req.startAsync();
            MServerSingleton.getInstance().getStuff(new Observer() {
                void onNewStuff(String stuff) {
                    try {
                        resp.getWriter().write(stuff + "\n\n");
                        resp.getWriter().flush();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
    
                void onThatWasAllStuff() {
                    context.complete();
                }
            });
        }
    }
    
    您可能需要调整超时以使其正常工作


    你可能想考虑使用.< /p>你可能需要在Servel1上创建一些消息队列,并使用长轮询来对它们进行重新排序,这样假设用户在页面等待加载时将保持标签打开25分钟。同意user979349,轮询系统(换句话说:一种异步设计以匹配问题的异步性质)是一种可行的方法。@Gimby-是,我假设用户将保持连接打开大约25分钟。@user979349-我不希望用户进行定期轮询,因为在智能手机中,这可能会影响电源效率。我希望servlet从MServer获得任何数据后立即通知用户。@Gimby-还有一件事,我不希望在25分钟后得到一个回复。我希望对同一请求有多个实时回复。类似于-User Request@0分钟。Servlet在2分钟后发送一些数据。然后,可能在7分钟后,Servlet会再次发送一些数据,而不需要用户执行任何操作。这种情况每隔几分钟就会发生一次。25分钟后,客户端-servlet连接终止。我不想从客户端进行轮询,这不能用普通的Servlet解决,因为Servlet只处理一个请求并提交一个响应。您可以使用WebSockets来代替HTML5或类似的框架来实现这一点。如果这个答案对您所做的任何事情都有帮助,请接受它作为答案。