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
, theDefaultServlet
is always named "default" and on the "default" servlet mapping of/
.If you have a need for more than one
DefaultServlet
then read the past answer at https://stackoverflow.com/a/20223103/775715See also the up to date jetty-examples on this subject.
Next, a
ServletContextHandler
cannot 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 theWebSocketServlet
as that will override theDefaultServlet
behaviors which is not what you want.Use the
WebSocketUpgradeFilter
instead, 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
ServletContextHandler
and a mix of url-patterns.