(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)
{
}
}