码头webSocket:java.lang.IllegalStateException:已提交
Posted
技术标签:
【中文标题】码头webSocket:java.lang.IllegalStateException:已提交【英文标题】:jetty webSocket : java.lang.IllegalStateException: Committed 【发布时间】:2012-09-19 03:00:13 【问题描述】:我在我的 Web 应用程序中使用 Jetty Websockets。
当我尝试重定向到注销 jsp 时,我收到此错误
oejs.ServletHandler:/test
java.lang.IllegalStateException: Committed
at org.eclipse.jetty.server.Response.resetBuffer(Response.java:1069)
at javax.servlet.ServletResponseWrapper.resetBuffer(ServletResponseWrapper.java:232)
at org.eclipse.jetty.http.gzip.GzipResponseWrapper.resetBuffer(GzipResponseWrapper.java:273)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:199)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:98)
这是我重定向的方式
RequestDispatcher rd = request.getRequestDispatcher("logoff.jsp");
rd.forward(request, response);
这个错误是不可重现的,但是你能告诉我它什么时候会发生吗??
【问题讨论】:
你说的“这个错误不可重现”是什么意思?是否偶尔发生? 如果有帮助,请考虑接受我的回复。 【参考方案1】:java.lang.IllegalStateException: 提交
我想我会对异常的含义提供更一般的解释。首先,Jetty 应该对异常消息感到羞耻。它对开发人员几乎没有帮助,除非他们已经知道它的实际含义。异常应该是这样的:
java.lang.IllegalStateException:响应标头已发送。您是否在发送内容后尝试返回结果?
当你去打电话时,通常会发生这种异常:
resp.getOutputStream(); // or getWriter()
然后尝试进行重定向或其他操作:
resp.sendRedirect("/someOtherUrl");
// or
return new ModelAndView("redirect:/someOtherUrl");
一旦您获得OutputStream
或Writer
以便您可以将正文字节写入客户端,Jetty 必须提交响应并发送 HTTP 200
和相关的标头,以便它可以开始返回正文字节。一旦发生这种情况,您就不能进行重定向,也不能对状态代码或标头进行任何其他更改。
返回正文字节后,正确的做法是从处理程序返回null
,而不是ModelAndView(...)
,或者只是将处理程序更改为返回void
。
【讨论】:
【参考方案2】:当您在自己的方法实现中调用超级方法时也会出现此异常。
例子:
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
super.doPost(req, resp); // <-- THIS IS THE PROBLEM
resp.sendRedirect("/someOtherUrl");
【讨论】:
我认为这不是真的,除非超类实际提交响应。看我的回答。【参考方案3】:这是因为您的响应已经处理了重定向请求,您正在尝试修改已提交的响应。
解决这个问题的一般方法有两种:
-
找出第一个重定向的位置并尝试修改逻辑以防止发生“两次重定向”的情况。
在每次重定向后添加“return”(我个人推荐此解决方案)。
【讨论】:
【参考方案4】:我这边的原因是使用了错误网址的码头:
对:http://localhost:8080
错误:http://localhost:8080/test
【讨论】:
【参考方案5】:假设您在 Jetty 服务器上运行 javax.servlet.Filter
,并且您面临同样的异常。这里的问题可以完全按照 Gray 的描述来描述(感谢 Gray)。通常,当您打电话时会发生此异常:
resp.getOutputStream(); // or getWriter()
然后
chain.doFilter(request, response);
如果您调用了resp.getOutputStream();
,请确保您没有在同一请求中使用chain.doFilter(request, response);
。
【讨论】:
【参考方案6】:在我的情况下,我的 @Service
中有一些存储库,我在课程开始时将其声明为 RepositoryFoo repositoryFoo;
我忘记添加@Autowired
甚至忘记添加private
,所以它编译得很好,然后在运行时我得到了这个java.lang.IllegalStateException: Committed
...我在找出原因之前浪费了一些时间!
【讨论】:
以上是关于码头webSocket:java.lang.IllegalStateException:已提交的主要内容,如果未能解决你的问题,请参考以下文章
码头webSocket:java.lang.IllegalStateException:已提交