已为此响应调用 Tomcat、Comet 和 getOutputStream()

发布于 2024-10-24 08:13:14 字数 1370 浏览 5 评论 0原文

我使用 Tomcat 6.0.32 和 Http11NioProtocol 连接器来实​​现长轮询。

我的彗星处理器将 HttpSevletResponse 保留在队列中,直到事件准备好发回。当它发送回事件时,它正在将二进制流写入小程序,因此我使用response.getOutputStream().write()来发送回数据。当写入流时,它是同步的。

当第二个框架中的另一个网页重新加载(从同一容器中的 SpringController 生成的独立 JSP)时,我偶尔会在日志中看到此情况,并且页面无法加载。

当同时请求彗星处理器和常规 servlet 生成的响应时,两者之间是否可能存在并发错误?

堆栈跟踪:

java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:611)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:198)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:180)
at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:118)
at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:77)
at org.apache.jsp.WEB_002dINF.jsp.sale_jsp._jspService(sale_jsp.java:96)

I am using Tomcat 6.0.32 with the Http11NioProtocol connector to implement long polling.

My comet processor is holding the HttpSevletResponse on a queue until an event is ready to send back. When it sends back the event it is writing a binary stream to an applet, so I use response.getOutputStream().write() to send data back. When writing to the stream it is synchronized.

When another web page in a second frame reloads (Independent JSP generated from SpringController in same container) occasionally I see this in the logs and the page fails to load.

Is it possible there is a concurrency error between a response generated from a comet processor and a regular servlet when both are requested at the same time?

The stack trace:

java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:611)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:198)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:180)
at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:118)
at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:77)
at org.apache.jsp.WEB_002dINF.jsp.sale_jsp._jspService(sale_jsp.java:96)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花开雨落又逢春i 2024-10-31 08:13:14

正如您在堆栈跟踪中看到的,JSP 调用了 response.getWriter(),但异常消息表明之前曾调用过 response.getOutputStream()。您不能对同一响应对象调用这两种方法。

这就是问题所在,我不知道如何在您的具体情况下解决它。

As you can see in the stack trace, the JSP calls response.getWriter(), but the exception message says there was a call to response.getOutputStream() before. You cannot call both methods on the same response object.

This is the problem, I don't know how to solve it in your specific context..

扛起拖把扫天下 2024-10-31 08:13:14

关于可能的并发性:我不这么认为。
您的长池 Servlet 在另一个线程中执行,具有自己的 HttpRequest 和自己的 HttpResponse

您的问题位于 JSP 中,如下所示:sale_jsp.java:96
响应中已提交某些内容,因此不允许您使用 getOutputStream()

在 JSP 中非常非常简单,这是一个简单的示例:

<%@ page language="java" contentType="text/html;" %>
<%@ page import="java.io.*" %>

<% OutputStream os = response.getOutputStream(); 
   os.write(......);
%>

生成的 Servlet 至少会在 OutputStream os = response.getOutputStream( ),这样你就完成了..
为了避免这种情况,请删除 %><% 之间的所有空格,如下所示:

<%@ page language="java" contentType="text/html;"
    import="java.io.*"   %><%

    OutputStream os = response.getOutputStream(); 
   os.write(......);
%>

配置您的 Tomcat 保留生成的代码
查看为 sale.jsp 生成的代码,我相信您会发现问题所在。

另外,请小心 <%! 您应该声明一些变量并无意中在该 JSP 上的所有请求上共享它们,这可能会导致这种并发...

About the possible concurrency: I don'y think so.
Your long pooling Servlet is executed in another Thread, with its own HttpRequest and its own HttpResponse.

Your problem is located in your JSP as indicated: sale_jsp.java:96
Something is already commited in the response, so you're not allowed to use getOutputStream().

And it's very very easy in a JSP, this is a simple example:

<%@ page language="java" contentType="text/html;" %>
<%@ page import="java.io.*" %>

<% OutputStream os = response.getOutputStream(); 
   os.write(......);
%>

The generated Servlet will, at least, print 3 '\n' in the output before OutputStream os = response.getOutputStream(), so you're done..
To avoid this, remove every white spaces between %> and <%, like this:

<%@ page language="java" contentType="text/html;"
    import="java.io.*"   %><%

    OutputStream os = response.getOutputStream(); 
   os.write(......);
%>

Configure your Tomcat to keep the code generated.
Have a look to the generated code for your sale.jsp , I'm sure you'll find out what's wrong.

Also, be careful with <%! you should declare some variables and share them unintentionally over ALL requests on this JSP this could lead to that kind of concurrency...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文