I'm trying to run an embedded Jetty websocket server with different content in different contexts.
The websocket part works if I put it in the / context, but I want to server other content there. The websocket part doesn't work if I put it into any other context.
Here is my code:
public WebsocketServer(int port, Model model, SessionManager sessionManager) throws Exception {
Server server = new Server(port);
server.setRequestLog((request, response) -> log_.info("request {}", request));
ContextHandlerCollection handlers = new ContextHandlerCollection();
ServletContextHandler sch;
sch = new ServletContextHandler();
sch.setContextPath("/model");
sch.addServlet(new ServletHolder(new ModelServlet(model)), "/");
sch.setResourceBase("cfg");
handlers.addHandler(sch);
sch = new ServletContextHandler();
sch.setContextPath("/web");
sch.addServlet(DefaultServlet.class, "/*");
sch.setResourceBase("cfg");
sch.setWelcomeFiles(new String[]{"websocket.html"});
handlers.addHandler(sch);
sch = new ServletContextHandler();
sch.setContextPath("/"); // <---- would like to change this context to /ws
Servlet websocketServlet = new JettyWebSocketServlet() {
@Override
protected void configure(JettyWebSocketServletFactory factory) {
factory.addMapping("/", (req, res) -> {
Session s = new Session(req);
sessionManager.add(s);
return s;
});
}
};
sch.addServlet(new ServletHolder(websocketServlet), "/");
JettyWebSocketServletContainerInitializer.configure(sch, null);
handlers.addHandler(sch);
sch = new ServletContextHandler();
sch.setContextPath("/*");
sch.addServlet(DefaultServlet.class, "/*");
sch.setResourceBase("cfg");
handlers.addHandler(sch);
server.setHandler(handlers);
server.start();
}
If I put my JettyWebSocketServlet in the / context, it works, but then it never gets to my DefaultServlet. I have tried changing my JettyWebSocketServlet to /ws, but then my webpage can't connect, but I do get the result from my DefaultServlet. My ModelServlet works in the /model context in either case.
My webpage tries to connect to ws://localhost:8080/ws
I am using jetty 11.0.16
Jetty 11 is now at End of Community Support
See: https://github.com/jetty/jetty.project/issues/10485
You have a few fundamental mistakes in your setup.
Your setup also gains nothing by splitting it up into different ServletContexts.
First, your use of
DefaultServlet, theDefaultServletis always named "default" and on the "default" servlet mapping of/.If you have a need for more than one
DefaultServletthen read the past answer at https://stackoverflow.com/a/20223103/775715See also the up to date jetty-examples on this subject.
Next, a
ServletContextHandlercannot have a context-path with a glob symbol.This is bad, and will not be used unless you somehow send a "*" in the URI path itself.
Lastly, if you want websocket to be on
/, then don't use theWebSocketServletas that will override theDefaultServletbehaviors which is not what you want.Use the
WebSocketUpgradeFilterinstead, as this will not interfere with other requests to/or/*that are not websocket requests.See the examples at
Lastly, your setup is overly complicated.
You can accomplish everything you want to do, with just 1
ServletContextHandlerand a mix of url-patterns.