java - 如何在 Jetty 中设置多个处理程序并且在启动过程中不会出错
问题描述
我有一些看起来像这样的服务器代码:
private WebAppContext getAspireWebAppContext() {
WebAppContext root = new WebAppContext();
root.setWar(config().<String>property("war.file"));
root.setContextPath("/");
return root;
}
private Server startWebApp(int port) {
try {
server.setConnectors(createConnectors(port));
ServletContextHandler context = getAspireWebAppContext();
server.setHandler(context);
// Ensure that a websocket always has a HttpSession
context.addFilter(HttpSessionForWebsocketFilter.class,"/ws/*",null);
// add websocket support
ServerContainer wscontainer = WebSocketServerContainerInitializer.configureContext( context );
wscontainer.addEndpoint(EngineSocket.class);
wscontainer.addEndpoint(WorkbenchSocket.class);
server.start();
} ....
}
我想使用一个HandlerList
,所以我可以添加一个 RewriteHandler。所以我试图改变它:
HandlerList handlers = new HandlerList();
server.setConnectors(createConnectors(port));
ServletContextHandler context = getAspireWebAppContext();
// server.setHandler(context);
handlers.addHandler(context);
// Ensure that a websocket always has a HttpSession
context.addFilter(HttpSessionForWebsocketFilter.class,"/ws/*",null);
// add websocket support
ServerContainer wscontainer = WebSocketServerContainerInitializer.configureContext( context );
wscontainer.addEndpoint(EngineSocket.class);
wscontainer.addEndpoint(WorkbenchSocket.class);
// RewriteHandler stuff
// handlers.addHandler(rewrite);
server.setHandler(handlers);
server.start();
即使在我添加更多处理程序之前,这也会导致WebSocketServerContainerInitializer.configureContext(context)
行上出现空异常:
引起:org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer.configureContext(WebSocketServerContainerInitializer.java:148) 处的 java.lang.NullPointerException
我在某个地方读到了context.setServer(server);
可能有帮助但无济于事的地方。我究竟做错了什么?谢谢
解决方案
首先添加HandlerList
到服务器。
Server server = new Server();
HandlerList handlers = new HandlerList();
server.setHandler(handlers);
ServletContextHandler context = getAspireWebAppContext();
handlers.addHandler(context);
ServerContainer wscontainer = WebSocketServerContainerInitializer.configureContext( context );
wscontainer.addEndpoint(EngineSocket.class);
wscontainer.addEndpoint(WorkbenchSocket.class);
// RewriteHandler stuff
handlers.addHandler(rewrite);
server.start();
但归根结底,这个 NPE 是一个内部尝试从属于您HttpClient
的.Server
ServletContextHandler
打开为https://github.com/eclipse/jetty.project/issues/3139
另外值得注意的是,您应该知道您不能可靠地将过滤器应用于 WebSocket 连接。
通过 JSR356(您选择使用的 API)进行的 WebSocket 升级旨在在过滤器链之外进行升级。这是因为过滤器可以修改请求/响应,更改响应的提交状态,包装输入流,包装输出流等。在 WebSocket 升级期间,所有这些都是被禁止的。虽然您的过滤器可能会在某些时候工作,但它不会 100% 工作。并且Set-Cookie
这种操作的标头也不能保证在响应中被发回。
如果您切换到 Jetty Native WebSocket API,您可以控制升级发生的位置(同样的禁止操作适用)。扩展自WebSocketServlet
,或扩展自WebSocketUpgradeFilter
并应用您自己的逻辑,或者更好的是,提供您自己的逻辑WebSocketCreator
来做您需要的事情。
推荐阅读
- android - 适用于 Android 6 和 7/8 的位置权限问题
- sql - 从 2 个表中查询匹配条件的 SQL
- python - Paramiko - 错误的身份验证类型 [Cisco SG-300 交换机]
- php - PHPML库问题
- r - 安装具有依赖项 R 的重复包
- google-sheets - 带有 OR 但没有 SUM 的 COUNTIFS
- asp.net - Asp 网络表单 C# 中的 Elmah 页面限制
- bash - 无法在 Docker 中构建最新的 Jenkins
- spring - 如何在应用程序启动并运行时重新加载 WebSecurityConfigurerAdapter 的 Configure 方法
- javascript - 从 Angular 6 调用时,节点中的 Passport-azure-ad 不会重定向到 Microsoft 登录页面