我在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);
此错误不可重现,但请您告诉我何时可能发生?
答案 0 :(得分:13)
java.lang.IllegalStateException:Committed
我以为我会对异常的含义提供更一般的解释。首先,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
。
答案 1 :(得分:2)
当您在自己的方法实现中调用super方法时,也会遇到此异常。
示例:
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
super.doPost(req, resp); // <-- THIS IS THE PROBLEM
resp.sendRedirect("/someOtherUrl");
}
答案 2 :(得分:1)
这是因为您的响应已经处理了重定向请求,您正在尝试修改已提交的响应。
有两种解决方法:
答案 3 :(得分:1)
我这边的原因是使用错误网址的码头:
右:http://localhost:8080
错误:http://localhost:8080/test
答案 4 :(得分:0)
考虑您在Jetty服务器上运行javax.servlet.Filter
,并且您面临同样的异常。这里的问题可以完全描述为格雷的描述(谢谢格雷)。通常,当您去呼叫时会发生此异常:
resp.getOutputStream(); // or getWriter()
然后
chain.doFilter(request, response);
如果您致电resp.getOutputStream();
,请确保您没有在同一请求中使用chain.doFilter(request, response);
。
答案 5 :(得分:0)
在我的情况下,我的@Service
中有一些存储库,并在课程开始时将其声明为RepositoryFoo repositoryFoo;
我忘记添加@Autowired
甚至使其private
,所以它编译良好,然后在运行时我有了这个java.lang.IllegalStateException: Committed
...我在弄清楚原因之前浪费了一些时间!