(The easy way would be to use auto-wiring in Spring, Guice, or CDI to accomplish this. But I'll assume you are not using those technologies.)
There's really only 1 reliable place to do this with JSR-356 that I can think of, and that's during Servlet context init, using a manual addition of the WebSocket endpoint to the javax.websocket.server.ServerContainer.
This is how it works ...
That obtains the reference to the javax.websocket.server.ServerContainer and then adds manually adds an Endpoint with a ServerEndpointConfig that has a built-up ServerEndpointConfig.Configurator with a reference to the javax.servlet.ServletContext (Obtained at the context init timeframe).
Note: Do not use annotated websocket endpoints, as the annotations will be auto discovered and auto deployed (along with the annotation provided configurator)
Something like this ...
package jetty.websocket;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.websocket.DeploymentException;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import javax.websocket.Session;
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpointConfig;
public class JsrManualEndpointWithServletContext implements ServletContextListener
{
public static class MyEndpoint extends Endpoint
{
private final ServletContext context;
public MyEndpoint(ServletContext context)
{
this.context = context;
}
@Override
public void onOpen(Session session, EndpointConfig config)
{
session.addMessageHandler(new MessageHandler.Whole<String>()
{
@Override
public void onMessage(String message)
{
session.getAsyncRemote().sendText("Context Path: " + context.getContextPath());
}
});
}
}
public static class MyEndpointConfigurator extends ServerEndpointConfig.Configurator
{
private final ServletContext context;
public MyEndpointConfigurator(ServletContext context)
{
this.context = context;
}
@Override
public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException
{
return (T) new MyEndpoint(context);
}
}
public void contextInitialized(ServletContextEvent sce)
{
ServletContext context = sce.getServletContext();
ServerEndpointConfig endpointConfig = ServerEndpointConfig.Builder.create(MyEndpoint.class, "/ws/*")
.configurator(new MyEndpointConfigurator(context))
.build();
ServerContainer wsContainer = (ServerContainer) context.getAttribute(ServerContainer.class.getName());
try
{
wsContainer.addEndpoint(endpointConfig);
}
catch (DeploymentException e)
{
// Let container know that something seriously wrong occurred.
throw new RuntimeException("Unable to deploy websocket", e);
}
}
@Override
public void contextDestroyed(ServletContextEvent sce)
{
}
}