Javaservlet中的异步行为?
我第一次尝试设计一个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通信的代码也已准备就绪。但我不知道
任何帮助都将不胜感激 您可能需要在客户端实现连续检查,在服务器端实现队列。换句话说,客户机将每隔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或类似的框架来实现这一点。如果这个答案对您所做的任何事情都有帮助,请接受它作为答案。