I need to set Servlet (only servlet not handler because of some reasons) to work with files outside war. Here https://stackoverflow.com/a/28735121/5057736 I found the following solution:
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);
This solutions works and this 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 result is the same - I get not found
. Why? How can I make it work with this certain context? I use jetty 9.2.15 because of the same reasons.
The
DefaultServlet
is designed to look at the request URI after thecontextPath
.In your example code when you changed the url-pattern of your servlet from
/
to/foo/*
the resulting file being looked for on disk is now includes the/foo/
portion.In other words, a request URI of
/css/main.css
results in the file (on disk) it expects to find as./src/webapp/foo/css/main.css
Your example has a few flaws. It's not a wise have an empty resource base for your
ServletContextHandler
, as theServletContext
itself needs access to that configuration value.You would fix that by removing ...
and using ServletContextHandler.setBaseResource(Resource) instead ...
This will allow the following
ServletContext
methods (used by countless servlet libraries) to work as wellString getRealPath(String path)
URL getResource(String path)
InputStream getResourceAsStream(String path)
Set<String> getResources(String path)
Finally, to make this setup sane in the
ServletContextHandler
, you'll add thedefault
Servlet name, on the "default url-pattern", which happens to be implemented as theDefaultServlet
.Like this:
Now, if you also have a need to serve static content from request URI
/foo/*
out of a directory not belonging to the webapp, you can do that too. That will require you to setup anotherDefaultServlet
that does not participate in theServletContext
.An example of this setup is ...
This uses a second
DefaultServlet
, using a unique resource base for thatDefaultServlet
only, and mapped to a url-pattern that ends in/*
.Finally, the init-parameter for this second
DefaultServlet
is told to use the pathInfo of the Request URI and not split on the contextPath like it normally does.This stand alone
DefaultServlet
declaration does not participate in theServletContext
and libraries will not be able to see or access the content from thatDefaultServlet
via theServletContext
methods. However all incoming HTTP client requests can request the content easily via that url-pattern.