Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add more than one resource directory to jetty

Looking to use multiple static directories with Jetty. When the server runs:

  http://localhost:8282/A
  http://localhost:8282/B 
  http://localhost:8282/C
  • A is placed in X/V/A
  • B is placed in Q/Z/B
  • C is placed in P/T/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?

like image 726
yoav.str Avatar asked Jul 10 '12 09:07

yoav.str


2 Answers

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 );
like image 181
pna Avatar answered Nov 07 '22 12:11

pna


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.

like image 34
haui Avatar answered Nov 07 '22 10:11

haui