拥有一个 Spring Boot 应用程序,其中 Jetty 作为嵌入式 Web 服务器和自定义 Jetty 错误处理程序。自定义错误处理程序之前曾工作过,但在某些 Spring Boot / Jetty 升级之后,自定义错误处理程序已停止使用。
使用:Spring Boot 3.1.10 和 Jetty 11.0.20
错误处理程序设置如下:
public class AcmeApiApp implements WebServerFactoryCustomizer<JettyServletWebServerFactory> {
...
@Override
public void customize(JettyServletWebServerFactory factory) {
JettyServerCustomizer customizer = server -> server.setErrorHandler(new SilentErrorHandler());
factory.addServerCustomizers(customizer);
}
private static final class SilentErrorHandler extends ErrorHandler {
...
}
...
}
错误处理程序不会用于无效请求。相反,使用
JettyEmbeddedErrorHandler
。
$ curl -H "Content-Type: invalid" http://localhost:8090
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/>
<title>Error 400 Bad Request</title>
</head>
<body><h2>HTTP ERROR 400 Bad Request</h2>
<table>
<tr><th>URI:</th><td>/</td></tr>
<tr><th>STATUS:</th><td>400</td></tr>
<tr><th>MESSAGE:</th><td>Bad Request</td></tr>
<tr><th>SERVLET:</th><td>org.eclipse.jetty.servlet.ServletHandler$Default404Servlet-6d66d76a</td></tr>
</table>
</body>
</html>
已将问题定位至:
org.eclipse.jetty.server.handler.ErrorHandler.getErrorHandler()
public static ErrorHandler getErrorHandler(Server server, ContextHandler context) {
ErrorHandler errorHandler = null;
if (context != null) {
errorHandler = context.getErrorHandler();
}
if (errorHandler == null && server != null) {
errorHandler = (ErrorHandler)server.getBean(ErrorHandler.class);
}
return errorHandler;
}
服务器对象具有自定义错误处理程序
server.getBean(ErrorHandler.class) = SilentErrorHandler
,但 context
不为空且 context.getErrorHandler()
为 JettyEmbeddedErrorHandler
。
如何配置以便始终使用自定义处理程序?
任何帮助表示赞赏!
Jetty 11 现已终止社区支持,此时您应该使用 Jetty 12。
您似乎正在将 Spring 与 Servlet 结合使用。
在
ErrorPageErrorHandler
或 ServletContextHandler
上设置 WebAppContext
,这是 Servlet 规范的一个功能,它有自己的错误处理(以及围绕它的大量配置)
您所做的只是设置服务器级别
ErrorHandler
,它用于所有不在 Servlet 上下文中的事物。
谢谢乔金。以下解决了它:
ErrorHandler errorHandler = new SilentErrorHandler();
server.setErrorHandler(errorHandler);
server.getHandlers().forEach((handler) -> {
if (handler instanceof WebAppContext webAppContext) {
webAppContext.addConfiguration(new AbstractConfiguration(new AbstractConfiguration.Builder()) {
@Override
public void configure(WebAppContext context) throws Exception {
context.setErrorHandler(errorHandler);
}
});
}
});