关于重定向的奇怪码头警告 "java.lang.IllegalStateException: Committed",如何解决?
Strange jetty warning "java.lang.IllegalStateException: Committed" on redirecting, how to fix it?
我有一个自定义 Jetty 重定向处理程序:
object RedirectHandler extends HandlerWrapper {
override def handle(
target: String,
baseRequest: Request,
request: HttpServletRequest,
response: HttpServletResponse
): Unit = {
require(!response.isCommitted)
val redirectURIOpt = rewrite(request.getRequestURI)
redirectURIOpt.foreach { v =>
response.sendRedirect(v)
require(response.isCommitted)
}
}
def rewrite(target: String): Option[String] = {
if (target.endsWith(".html")) None
else {
var _target = target.stripSuffix("/")
if (_target.nonEmpty) {
_target += ".html"
Some(_target)
} else {
None
}
}
}
}
它配置为与普通 ResourceHandler 一起设置 Web 服务器:
...
val server = new Server(10092)
val resourceHandler = new ResourceHandler
resourceHandler.setDirectoriesListed(true)
// resource_handler.setWelcomeFiles(Array[String]("test-sites.html"))
resourceHandler.setResourceBase(CommonConst.USER_DIR \ "test-sites")
val handlers = new HandlerList
handlers.setHandlers(Array(RedirectHandler, resourceHandler))
server.setHandler(handlers)
每次触发重定向时,我都发现了一条奇怪的警告信息:
WARN HttpChannel: /test-sites/e-commerce/static
java.lang.IllegalStateException: Committed
at org.sparkproject.jetty.server.HttpChannel.resetBuffer(HttpChannel.java:994)
at org.sparkproject.jetty.server.HttpOutput.resetBuffer(HttpOutput.java:1459)
at org.sparkproject.jetty.server.Response.resetBuffer(Response.java:1217)
at org.sparkproject.jetty.server.Response.sendRedirect(Response.java:569)
at org.sparkproject.jetty.server.Response.sendRedirect(Response.java:503)
at org.sparkproject.jetty.server.Response.sendRedirect(Response.java:578)
at org.sparkproject.jetty.server.ResourceService.sendWelcome(ResourceService.java:398)
at org.sparkproject.jetty.server.ResourceService.doGet(ResourceService.java:257)
at org.sparkproject.jetty.server.handler.ResourceHandler.handle(ResourceHandler.java:262)
at org.sparkproject.jetty.server.handler.HandlerList.handle(HandlerList.java:59)
at org.sparkproject.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.sparkproject.jetty.server.Server.handle(Server.java:516)
at org.sparkproject.jetty.server.HttpChannel.lambda$handle(HttpChannel.java:388)
at org.sparkproject.jetty.server.HttpChannel.dispatch(HttpChannel.java:633)
at org.sparkproject.jetty.server.HttpChannel.handle(HttpChannel.java:380)
at org.sparkproject.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
at org.sparkproject.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
at org.sparkproject.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.sparkproject.jetty.io.ChannelEndPoint.run(ChannelEndPoint.java:104)
at org.sparkproject.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
at org.sparkproject.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
at java.lang.Thread.run(Thread.java:748)
据此post:
jetty webSocket : java.lang.IllegalStateException: Committed
如果响应在 sendRedirect
之后被进一步篡改,就会触发该问题。但是,鉴于 resourceHandler
是一个非常成熟的组件,不太可能犯这种低级错误。
那么可能的原因是什么,更重要的是,如何通过将重定向响应声明为最终响应来修复它?
您错过了 baseRequest.setHandled(true)
告诉 Jetty 停止处理进一步的处理程序。当您的处理程序产生响应(或处理请求)时使用它。
后来的处理程序(ResourceHandler
根据您的堆栈跟踪)尝试写入响应并被击倒,因为响应已经提交。
我有一个自定义 Jetty 重定向处理程序:
object RedirectHandler extends HandlerWrapper {
override def handle(
target: String,
baseRequest: Request,
request: HttpServletRequest,
response: HttpServletResponse
): Unit = {
require(!response.isCommitted)
val redirectURIOpt = rewrite(request.getRequestURI)
redirectURIOpt.foreach { v =>
response.sendRedirect(v)
require(response.isCommitted)
}
}
def rewrite(target: String): Option[String] = {
if (target.endsWith(".html")) None
else {
var _target = target.stripSuffix("/")
if (_target.nonEmpty) {
_target += ".html"
Some(_target)
} else {
None
}
}
}
}
它配置为与普通 ResourceHandler 一起设置 Web 服务器:
...
val server = new Server(10092)
val resourceHandler = new ResourceHandler
resourceHandler.setDirectoriesListed(true)
// resource_handler.setWelcomeFiles(Array[String]("test-sites.html"))
resourceHandler.setResourceBase(CommonConst.USER_DIR \ "test-sites")
val handlers = new HandlerList
handlers.setHandlers(Array(RedirectHandler, resourceHandler))
server.setHandler(handlers)
每次触发重定向时,我都发现了一条奇怪的警告信息:
WARN HttpChannel: /test-sites/e-commerce/static
java.lang.IllegalStateException: Committed
at org.sparkproject.jetty.server.HttpChannel.resetBuffer(HttpChannel.java:994)
at org.sparkproject.jetty.server.HttpOutput.resetBuffer(HttpOutput.java:1459)
at org.sparkproject.jetty.server.Response.resetBuffer(Response.java:1217)
at org.sparkproject.jetty.server.Response.sendRedirect(Response.java:569)
at org.sparkproject.jetty.server.Response.sendRedirect(Response.java:503)
at org.sparkproject.jetty.server.Response.sendRedirect(Response.java:578)
at org.sparkproject.jetty.server.ResourceService.sendWelcome(ResourceService.java:398)
at org.sparkproject.jetty.server.ResourceService.doGet(ResourceService.java:257)
at org.sparkproject.jetty.server.handler.ResourceHandler.handle(ResourceHandler.java:262)
at org.sparkproject.jetty.server.handler.HandlerList.handle(HandlerList.java:59)
at org.sparkproject.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.sparkproject.jetty.server.Server.handle(Server.java:516)
at org.sparkproject.jetty.server.HttpChannel.lambda$handle(HttpChannel.java:388)
at org.sparkproject.jetty.server.HttpChannel.dispatch(HttpChannel.java:633)
at org.sparkproject.jetty.server.HttpChannel.handle(HttpChannel.java:380)
at org.sparkproject.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
at org.sparkproject.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
at org.sparkproject.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.sparkproject.jetty.io.ChannelEndPoint.run(ChannelEndPoint.java:104)
at org.sparkproject.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
at org.sparkproject.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
at java.lang.Thread.run(Thread.java:748)
据此post:
jetty webSocket : java.lang.IllegalStateException: Committed
如果响应在 sendRedirect
之后被进一步篡改,就会触发该问题。但是,鉴于 resourceHandler
是一个非常成熟的组件,不太可能犯这种低级错误。
那么可能的原因是什么,更重要的是,如何通过将重定向响应声明为最终响应来修复它?
您错过了 baseRequest.setHandled(true)
告诉 Jetty 停止处理进一步的处理程序。当您的处理程序产生响应(或处理请求)时使用它。
后来的处理程序(ResourceHandler
根据您的堆栈跟踪)尝试写入响应并被击倒,因为响应已经提交。