Looking to use multiple static directories with Jetty. When the server runs:
http://localhost:8282/A
http://localhost:8282/B
http://localhost:8282/C
The following failed:
ResourceHandler resource_handler = new ResourceHandler();
resource_handler.setWelcomeFiles(new String[]{"index.html"});
resource_handler.setResourceBase(HTML_SITE);
ResourceHandler resource_handler1 = new ResourceHandler();
resource_handler1.setWelcomeFiles(new String[]{"index.html"});
resource_handler1.setResourceBase(HTML_CLIENTZONE_SITE);
// deploy engine
WebAppContext webapp = new WebAppContext();
String dir = System.getProperty("user.dir");
webapp.setResourceBase(getWebAppPath());
webapp.setContextPath("/");
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[]{resource_handler,resource_handler1 ,webapp, new DefaultHandler()});
server.setHandler(handlers);
How can I add more than one static resource directory?
Since 6.1.12, this is supported by using a ResourceCollection to the WebAppContext's base resource:
Server server = new Server(8282);
WebAppContext context = new WebAppContext();
context.setContextPath("/");
ResourceCollection resources = new ResourceCollection(new String[] {
"project/webapp/folder",
"/root/static/folder/A",
"/root/static/folder/B",
});
context.setBaseResource(resources);
server.setHandler(context);
server.start();
To subsequently open a file, use the ServletContext (e.g., WebAppContext), which could be part of an interface definition, such as:
/**
* Opens a file using the servlet context.
*/
public default InputStream open( ServletContext context, String filename ) {
String f = System.getProperty( "file.separator" ) + filename;
return context.getResourceAsStream( f );
}
Such as:
InputStream in = open( context, "filename.txt" );
This will open filename.txt
if it exists in one of the given directories. Note that getResourceAsStream will return null
, rather than throw an exception, so it's a good idea to check for it:
public default InputStream validate( InputStream in, String filename )
throws FileNotFoundException {
if( in == null ) {
throw new FileNotFoundException( filename );
}
return in;
}
Then you can update the open
method as follows:
return validate( context.getResourceAsStream( filename ), filename );
If you want to "mount" independent resource directories to arbitrary URIs in the server namespace, using multiple instances of the DefaultServlet
with independent resourceBase
configurations is the best choice.
The following snippet will serve URIs /A/*
from filesystem path X/V/A
and /B/*
from filesystem path Q/Z/B
:
Server server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(Integer.parseInt(port));
server.addConnector(connector);
ServletContextHandler servletHandler = new ServletContextHandler(null, "/", true, false);
// Configuration for serving /A/* from X/V/A
DefaultServlet aServlet = new DefaultServlet();
ServletHolder aHolder = new ServletHolder(aServlet);
aHolder.setInitParameter("resourceBase", "X/V/A");
aHolder.setInitParameter("pathInfoOnly", "true");
servletHandler.addServlet(aHolder, "/A/*");
// Configuration for serving /B/* from Q/Z/B
DefaultServlet bServlet = new DefaultServlet();
ServletHolder bHolder = new ServletHolder(bServlet);
bHolder.setInitParameter("resourceBase", "Q/Z/B");
bHolder.setInitParameter("pathInfoOnly", "true");
servletHandler.addServlet(bHolder, "/B/*");
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { servletHandler });
server.setHandler(handlers);
server.start();
Note: As you can see from the code above, there is no need that the name of the directory from which /A/*
is served is exactly A
as in your example. Both names - the filesystem name of the directory to serve and the URI to map the contents to - are completely independent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With