码头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");

一旦您获得OutputStreamWriter 以便您可以将正文字节写入客户端,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 JSR 356 错误 403

码头 WebSocket 服务器

JAVA 码头 9 Websocket SSL

码头webSocket:java.lang.IllegalStateException:已提交

码头、websocket、java.lang.RuntimeException:无法加载平台配置器

如何使用同一端口(使用码头 8)拥有具有多个上下文的 websocket