栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

HttpServletResponse似乎会定期过早发送

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

HttpServletResponse似乎会定期过早发送

这是最有趣的一行:

this.sc.send(msg, new HTTPServletResponseListener(response));

我怀疑这

sc
是您正在呼叫的外部TCP服务器,并且您还会传递一个侦听器,以便在响应到达时得到通知。现在是一个重要的假设: TCP服务器异步发送响应
,在 另一个线程中 通知您的侦听器,对吗?

在这种情况下,它可以说明您的行为。在3.0之前的servlet中,您必须在中处理整个请求

doGet
。一旦您的代码离开
doGet()
,servlet容器就会假定整个请求已被处理并丢弃该请求。

您引入了一个 竞争条件

doGet()
不向输出流写入任何内容而返回。容器需要几毫秒来处理响应并将其发送回。如果您的外部TCP服务器在短时间内返回数​​据并通知侦听器,则数据将通过。但是,如果服务器速度稍慢,则您正在发送对已处理的连接的响应。

可以这样考虑:浏览器进行呼叫,然后

doGet()
又调用后端服务器。该
doGet()
回报和servlet容器假定你做。它发回(空)响应,而忽略了该请求。毫秒甚至几秒后的响应从后端服务器返回。但是连接不见了,它已经被发送,套接字被关闭,浏览器呈现了响应。您没有在告诉您的容器:
嘿,等等,我还没有完成回复!

解决方案

从最坏到最好:

  1. 积极等待/轮询中的响应

    doGet()

  2. 阻止您的外部TCP服务器调用。更改TCP服务器外观,使其 返回

    ResponseMessage
    并将侦听器代码移至
    doGet()
    。例:

         ResponseMessage responseMsg = this.sc.send(msg);     DataParser parser = new JSonParser();     String temp = parser.parseToString(responseMsg);     httpResponse.setContentType("application/json");     httpResponse.addHeader("Hmm","yup");     PrintWriter out = httpResponse.getWriter();     out.println(temp);
  1. 使用Servlet 3.0异步支持,这在您的用例中是一个更好的选择,更改范围将非常有限。

doGet()

    final AsyncContext asyncContext = request.startAsync(request, response);

并在

HTTPServletResponseListener
一旦你完成:

    asyncContext.complete();

额外的调用

startAsync()
告诉容器:
即使我从回来了
doGet()
,我也没有完成此请求。请稍等
。我前段时间写了一篇关于Servlet 3.0
的文章。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/506204.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号