Jetty: default servlet context path

I need to install Servlet (only the servlet is not a handler for some reason) to work with files outside the war. Here's the https://stackoverflow.com/a/3186168/2126258

Server server = new Server(8080); ServletContextHandler ctx = new ServletContextHandler(); ctx.setContextPath("/"); DefaultServlet defaultServlet = new DefaultServlet(); ServletHolder holderPwd = new ServletHolder("default", defaultServlet); holderPwd.setInitParameter("resourceBase", "./src/webapp/"); ctx.addServlet(holderPwd, "/*");//LINE N ctx.addServlet(InfoServiceSocketServlet.class, "/info"); server.setHandler(ctx); 

These solutions work, and that is what I need. However, it stops working as soon as I change LINE N to ctx.addServlet(holderPwd, "/foo/*"); . I tried "/ foo /", "/ foo", but the result is the same - I get not found . What for? How can I make it work with this specific context? I use berth 9.2.15 for the same reasons.

0
java servlets jetty embedded-jetty
Aug 18 '16 at 6:48
source share
1 answer

DefaultServlet intended for viewing request URI after contextPath .

In your sample code, when you change the url template of your servlet from / to /foo/* resulting file viewed on disk now includes the /foo/ .

In other words, the request URI /css/main.css causes the file (on disk) to be found as ./src/webapp/foo/css/main.css

There are several drawbacks in your example. It is not wise to have an empty resource base for your ServletContextHandler , since the ServletContext itself needs access to this configuration value.

You would fix it by deleting ...

 holderPwd.setInitParameter("resourceBase", "./src/webapp/"); 

and using ServletContextHandler.setBaseResource (Resource) instead ...

 ctx.setResourceBase(Resource.newResource(new File("./src/webapp"))); 

This will allow you to use the following ServletContext methods (used by countless servlet libraries)

  • String getRealPath(String path)
  • URL getResource(String path)
  • InputStream getResourceAsStream(String path)
  • Set<String> getResources(String path)

Finally, to make this setting workable in ServletContextHandler , you add the name of the default servlet to the " default url template", which appears to be implemented as DefaultServlet .

Like this:

 // Lastly, the default servlet for root content // It is important that this is added last. String defName = "default"; // the important "default" name ServletHolder holderDef = new ServletHolder(defName, DefaultServlet.class); holderDef.setInitParameter("dirAllowed","true"); ctx.addServlet(holderDef,"/"); // the servlet spec "default url-pattern" 

Now, if you also need to use static content from the request URI /foo/* from a directory that does not belong to webapp, you can also do this. This will require the installation of another DefaultServlet that is not involved in the ServletContext .

An example of this setting ...

 package jetty; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.resource.PathResource; import java.io.File; import java.nio.file.Path; public class ManyDefaultServlet { public static void main(String[] args) throws Exception { Server server = new Server(); ServerConnector connector = new ServerConnector(server); connector.setPort(8080); server.addConnector(connector); // The filesystem paths we will map Path homePath = new File(System.getProperty("user.home")).toPath().toRealPath(); Path pwdPath = new File(System.getProperty("user.dir")).toPath().toRealPath(); // 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.setBaseResource(new PathResource(pwdPath)); server.setHandler(context); // Fist, add special pathspec of "/home/" content mapped to the homePath ServletHolder holderHome = new ServletHolder("static-home", DefaultServlet.class); holderHome.setInitParameter("resourceBase",homePath.toUri().toASCIIString()); holderHome.setInitParameter("dirAllowed","true"); // Use request pathInfo, don't calculate from contextPath holderHome.setInitParameter("pathInfoOnly","true"); context.addServlet(holderHome,"/foo/*"); // must end in "/*" for pathInfo to work // Lastly, the default servlet for root content // It is important that this is last. String defName = "default"; // the important "default" name ServletHolder holderDef = new ServletHolder(defName, DefaultServlet.class); holderDef.setInitParameter("dirAllowed","true"); context.addServlet(holderDef,"/"); // the servlet spec "default url-pattern" server.start(); server.join(); } } 

This uses the second DefaultServlet , using a unique resource base for that DefaultServlet and matching the url pattern that ends with /* .

Finally, the init parameter for this second DefaultServlet prompted to use the pathInfo request URI, rather than breaking it into contextPath, as usual.

For more information that this is the entire pathInfo, request URIs, contextPath and url patterns ending in /* everything, see the helpful answer at @ 30thh

This stand-alone DefaultServlet declaration is not involved in the ServletContext , and libraries will not be able to see or access the contents of this DefaultServlet using the ServletContext methods. However, all incoming HTTP client requests can easily request content through this url template.

+6
Aug 18 '16 at 13:42 on
source share



All Articles