What is difference between ServletContextHandler.setResourceBase and ResourceHandler.setResourceBase when using Jetty embedded container?
I'm using embedded Jetty to create a static web site. Does ServletContextHandler.setResourceBase("...") have a same effect as ResourceHandler.setResourceBase("...")?
Example:
// ServletContextHandler case
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setResourceBase("/tmp/...");
// ResourceHandler case
ResourceHandler resourceHandler = new ResourceHandler();
resourceHandler.setResourceBase("/tmp/...");
I have tried test both of them. ResourceHandler works exactly what I want. But otherwise doesn't. What's the difference between them?
(Sorry for my poor English :P)
Update
After changed, below is whole code. Context("/") serves static files, wsContext("/ws") serves web socket endpoints. Of course Context("/") is able to serve web socket endpoints as well.
server = new Server();
server.setStopAtShutdown(true);
ServerConnector connector = new ServerConnector(server);
connector.setPort(8000);
server.addConnector(connector);
// Setup the basic application "context" for this application at "/"
// This is also known as the handler tree (in jetty speak)
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.setResourceBase(System.getProperty("webapp.path"));
ServletContextHandler wsContext = new ServletContextHandler();
wsContext.setContextPath("/ws");
ContextHandlerCollection contexts=new ContextHandlerCollection();
contexts.setHandlers(new Handler[]{context, wsContext});
server.setHandler(contexts);
context.addServlet(DefaultServlet.class, "/");
// Initialize javax.websocket layer
ServerContainer wsContainer = WebSocketServerContainerInitializer.configureContext(wsContext);
// Add WebSocket endpoint to javax.websocket layer
// code omitted...
server.start();
logger.info("WebServer started.");
Solution 1:
With that setup, the resourceHandler
will never be called, as the DefaultServlet
processing (or Default404Servlet
) at the end of the ServletContextHandler
chain will always respond, not allowing resourceHandler
to even execute.
If you have a ServletContextHandler
, do not use ResourceHandler
use the DefaultServlet
in that ServletContextHandler
to setup and serve your static files.
ResourceHandler
is very simplistic, if you want more control / features, use a DefaultServlet
configured in your ServletContextHandler
instead.
Ok, with that out of the way ...
The ServletContextHandler.setBaseResource(Resource)
is the place for the ServletContext
itself to configure its context-wide resourceBase
.
(Note: the parameter of setResourceBase() is a URL string that can point to a file://
directory or even a jar:file://
location. Pretty much anything supported by Resource.newResource(String)
)
-
${resourceBase}/
is the lookup point for various methods injavax.servlet.ServletContext
such as:String getRealPath(String path)
URL getResource(String path)
InputStream getResourceAsStream(String path)
Set<String> getResources(String path)
- Requested resources that don't match any of your servlets or filters, will then be handled by the
DefaultServlet
, which might serve static resources (such as*.html
,*.css
,*.js
) from the specified${resourceBase}/${request.pathInfo}
ResourceHandler
does not participate in ServletContextHandler
is an is inappropriate to mix with ServletContextHandler
.
Also, don't forget to set ServletContextHandler.setContextPath(String)
to your desired context path (usually "/"
)
And yes, you can even have multiple DefaultServlet
configurations in a single ServletContextHandler
.