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

时间:2018-11-23 14:55:11

标签: 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)行上导致空异常:

  

由以下原因引起:java.lang.NullPointerException   org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer.configureContext(WebSocketServerContainerInitializer.java:148)

我读到某处context.setServer(server);可能会有所帮助,但无济于事。我究竟做错了什么?谢谢

1 个答案:

答案 0 :(得分:1)

首先将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的{​​{1}}获取公用Server的错误。

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

还要注意,您应该知道不能将过滤器可靠地应用于WebSocket连接。

通过JSR356(您选择使用的API)进行WebSocket升级的目的是在Filter链之外进行升级。这是因为筛选器可以修改请求/响应,更改响应的提交状态,包装输入流,包装输出流等。在WebSocket升级期间,所有这些都被禁止。尽管您的过滤器有时可能会起作用,但它不会100%地起作用。并且也不保证此类操作的ServletContextHandler标头也将在响应中发送回去。

如果切换到Jetty本机WebSocket API,则可以控制升级的位置(适用相同的禁止措施)。从Set-Cookie扩展,或从WebSocketServlet扩展并应用您自己的逻辑,甚至更好的是,提供您自己的WebSocketUpgradeFilter来完成您需要的工作。