如何在 Jetty 中设置多个处理程序并且在启动期间不出错
How to set multiple handlers in Jetty and not get an error during startup
我有一些服务器代码,如下所示:
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)
行出现空异常:
Caused by: java.lang.NullPointerException at
org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer.configureContext(WebSocketServerContainerInitializer.java:148)
我在某处读到 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 是一个内部尝试从属于您的 ServletContextHandler
.
的 Server
中获取公共 HttpClient
的错误
打开为 https://github.com/eclipse/jetty.project/issues/3139
另外请注意,您应该知道无法可靠地将过滤器应用于 WebSocket 连接。
通过 JSR356 进行的 WebSocket 升级(您选择使用的 API)旨在在过滤器链之外进行升级。这是因为 Filter 可以修改 request/response、更改响应的提交状态、包装输入流、包装输出流等。所有这些在 WebSocket 升级期间都是被禁止的。虽然您的过滤器可能有时会起作用,但它不会在 100% 的时间内起作用。并且也不保证来自此类操作的 Set-Cookie
header 会在响应中发回。
如果您切换到 Jetty Native WebSocket API,您可以控制升级发生的位置(同样禁止的操作适用)。从 WebSocketServlet
扩展,或从 WebSocketUpgradeFilter
扩展并应用您自己的逻辑,或者更好的是,提供您自己的 WebSocketCreator
来执行您需要的操作。
我有一些服务器代码,如下所示:
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)
行出现空异常:
Caused by: java.lang.NullPointerException at org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer.configureContext(WebSocketServerContainerInitializer.java:148)
我在某处读到 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 是一个内部尝试从属于您的 ServletContextHandler
.
Server
中获取公共 HttpClient
的错误
打开为 https://github.com/eclipse/jetty.project/issues/3139
另外请注意,您应该知道无法可靠地将过滤器应用于 WebSocket 连接。
通过 JSR356 进行的 WebSocket 升级(您选择使用的 API)旨在在过滤器链之外进行升级。这是因为 Filter 可以修改 request/response、更改响应的提交状态、包装输入流、包装输出流等。所有这些在 WebSocket 升级期间都是被禁止的。虽然您的过滤器可能有时会起作用,但它不会在 100% 的时间内起作用。并且也不保证来自此类操作的 Set-Cookie
header 会在响应中发回。
如果您切换到 Jetty Native WebSocket API,您可以控制升级发生的位置(同样禁止的操作适用)。从 WebSocketServlet
扩展,或从 WebSocketUpgradeFilter
扩展并应用您自己的逻辑,或者更好的是,提供您自己的 WebSocketCreator
来执行您需要的操作。