简体   繁体   English

如何在 Jetty 中设置多个处理程序并且在启动过程中不会出错

[英]How to set multiple handlers in Jetty and not get an error during startup

I have some server code which looks like this:我有一些看起来像这样的服务器代码:

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();
  } ....
}

I want to use a HandlerList so I can add a RewriteHandler.我想使用一个HandlerList以便我可以添加一个 RewriteHandler。 So I tried to change it:所以我试图改变它:

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();

Even before I add any more handlers this causes a null exception on the WebSocketServerContainerInitializer.configureContext(context) line:甚至在我添加更多处理程序之前,这会导致WebSocketServerContainerInitializer.configureContext(context)行上的空异常:

Caused by: java.lang.NullPointerException at org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer.configureContext(WebSocketServerContainerInitializer.java:148)引起:java.lang.NullPointerException at org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer.configureContext(WebSocketServerContainerInitializer.java:148)

I read somewhere that context.setServer(server);我在某处读到了context.setServer(server); might help but to no avail.可能有帮助,但无济于事。 What am I doing wrong?我究竟做错了什么? Thanks谢谢

Add the HandlerList to the server first.首先将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();

But ultimately, this NPE is a bug with an internal attempt to fetch a common HttpClient from the Server that belongs to your ServletContextHandler .但最终,这个 NPE 是一个内部尝试HttpClient您的ServletContextHandlerServer获取公共HttpClient的错误。

Opened as https://github.com/eclipse/jetty.project/issues/3139打开为https://github.com/eclipse/jetty.project/issues/3139

Also of note, you should know that you cannot apply filters to WebSocket connections reliably.另外值得注意的是,您应该知道不能可靠地将过滤器应用于 WebSocket 连接。

WebSocket upgrades via JSR356 (the API you are choosing to use) is designed to do the upgrade outside of the Filter chain.通过 JSR356(您选择使用的 API)进行的 WebSocket 升级旨在在过滤器链之外进行升级。 This is because a Filter can modify the request/response, change commit state of the response, wrap input streams, wrap output streams, etc. All of which are forbidden during a WebSocket upgrade.这是因为过滤器可以修改请求/响应、更改响应的提交状态、包装输入流、包装输出流等。所有这些在 WebSocket 升级期间都是被禁止的。 While your Filter might work some of the time, it will not work 100% of the time.虽然您的过滤器有时可能会起作用,但它不会在 100% 的时间内起作用。 And the Set-Cookie header from such an action isn't guaranteed to be sent back on the response either.并且也不能保证在响应中发回来自此类操作的Set-Cookie标头。

If you switch to the Jetty Native WebSocket API you can control where the upgrade occurs (same forbidden actions apply).如果您切换到 Jetty Native WebSocket API,您可以控制升级发生的位置(同样的禁止操作适用)。 Extend from WebSocketServlet , or extend from WebSocketUpgradeFilter and apply your own logic, or even better, supply your own WebSocketCreator to do what you need.WebSocketServlet扩展,或者从WebSocketUpgradeFilter扩展并应用你自己的逻辑,或者更好的是,提供你自己的WebSocketCreator来做你需要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM