显然,doGet
方法的返回类型为void,因此,它不会返回任何内容。从这个意义上讲,我使用“return”这个词来表示将响应发送回请求它的客户端。
我正在尝试实现一个长轮询Servlet。如果我有一些我想要寄回的东西,那么它不会发送回应将是有益的。因此,在doGet方法中,我将连接用户的ID和AsyncContext添加到地图:
private ConcurrentMap<String, AsyncContext> contexts = new ConcurrentHashMap<>();
//...in the doGet method when I need to add the context...
contexts.put(userId, context);
然后,当我有东西要发回时,我可以检索适当的上下文并写入它的响应输出流:
AsyncContext context = contexts.get(userId);
PrintWriter writer = context.getResponse().getWriter();
writer.write("something to send to the client");
但是,客户似乎永远不会收到回应。查看浏览器开发人员控制台中的“网络”选项卡,我可以看到GET请求已发送,然后返回(状态为200)。这发生在我实际发送回来之前。这让我相信在doGet方法完成后会返回响应。也许正因为如此,在此之后,没有任何东西可以发送到客户端,因为没有打开连接。
一旦方法执行完毕,doGet方法是否会将响应发送给客户端?如果是这种情况,我如何保持连接打开以获得长轮询效果?
答案 0 :(得分:2)
回答我自己的问题:Does the doGet method send the response to the client once the method is finished executing?
是的,当doGet(或任何HttpServlet方法,例如:doGet,doPost等)方法完成执行时,它会将响应发送回客户端。
If this is the case, how can I keep the connection open for a long-polling effect?
使用异步Servlet(我正在使用,但是,我发现我的特定问题必须在其他地方,但这些答案仍然与所提出的问题相关)。在ServletRequest对象上调用startAsync方法,如下所示:
AsyncContext context = request.startAsync(request, response);
&#34;这将通知Web容器在请求调用结束时它应该释放处理线程并保持连接打开,以便其他线程写入响应并结束连接。&#34; {{ 3}}
另外,我将为我的特定问题添加解决方案(客户端没有收到响应)是因为在我的Servlet中,我没有在AsyncContext对象上调用完整方法:
asyncContext.complete();
答案 1 :(得分:1)
是的,当 doGet()完成执行时,会刷新并关闭响应流。
长时间占用UI线程违反了Java Enterprise的最佳做法。
如果没有任何响应,建议您立即返回,并在客户端(浏览器)端实现计时器,以便经常轮询服务器以获得结果。