Ruggs
Ruggs

Reputation: 1610

Wrap the default servlet but override the default webapp path

I have a folder of static html,imgs,flash content that lives outside of the webapp folder. Right now I'm using a symbolic link to map that folder into my webapp directory. The problem i have is when I undeploy my application it follows the symbolic link and deletes all these files.

One of the solutions I'm trying to implement is a special servlet that wraps the default servlet but uses a different relative path. I'm having trouble finding out how to wrap the default servlet in a way that overrides the default servlet path.

Here is what I'm working with:

public void doGet(final HttpServletRequest req, final HttpServletResponse resp)
    throws ServletException, IOException {
    final RequestDispatcher rd = getServletContext().getNamedDispatcher("default");
    final HttpServletRequest wrapped = new HttpServletRequestWrapper(req) {

        @Override
        public String getServletPath() {
            return "/usr/depot/repository";
        }
    };

    rd.forward(wrapped, resp);
}

Upvotes: 3

Views: 6697

Answers (6)

Robert Tupelo-Schneck
Robert Tupelo-Schneck

Reputation: 10543

You can change to a different path within your webapp context. Here's an example which does differential serving depending on whether the client's User-Agent supports ES6:

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    RequestDispatcher rd = getServletContext().getNamedDispatcher("default");
    HttpServletRequest wrapped = new HttpServletRequestWrapper(req) {
        @Override
        public String getServletPath() {
            String prefix = supportsES6(req) ? "/es6" : "/es5";
            String newPath =  prefix + req.getServletPath();
            if (newPath.endsWith("/")) newPath += "index.html";
            return newPath;
        }
    };
    rd.forward(wrapped, resp);
}

However, "es5" and "es6", even though we use the initial slash, are subdirectories of the webapp's ordinary context. It's not possible to break outside of the context directory using this method.

Upvotes: 0

kostmo
kostmo

Reputation: 6340

I have open-sourced a custom servlet that serves files from an arbitrary base path. Additionally, it supports file browsing inside nested compressed archives.

It's available here: https://bitbucket.org/teslamotors/zip-listing/overview

Upvotes: -1

BalusC
BalusC

Reputation: 1109222

You can override DefaultServlet with your own implementation. You can perfectly subclass it, it's a public class. Here are the functional specifications of the DefaultServlet, you need to adhere it.

On the other hand you can ignore DefaultServlet and go for your own solution, an example can be found here.

Upvotes: 3

ZZ Coder
ZZ Coder

Reputation: 75496

We have a similar problem that we need to share some files generated by CMS among several applications. Symlink is the easiest way to do this if you are not using Windows.

We setup 2 accounts for CMS and Tomcat. The files are read-only to Tomcat so it can't delete them.

You can also write a small Tomcat extension so it can look for files in multiple places. See this web site,

http://blog.bazoud.com/post/2009/05/12/Multiples-docbases-avec-tomcat

Your current approach won't work. Tomcat needs to load up all the resources in a cache on deploy for it to be available. It's too late to change that in request processing. This extension allows Tomcat load resources from multiple directories. The drawback of this approach is that you have to put a small JAR in server/lib.

Upvotes: 1

ChssPly76
ChssPly76

Reputation: 100736

You can either write your own servlet to serve static content (which is not that hard) or try to extend rather than wrap the DefaultServlet. Either way, your resulting servlet will have be configured in place of default in your web.xml (using "default" as servlet-name).

That said, DefaultServlet will only serve static content from under your webapp context; in order to change that you'll have to create / bind to JNDI your own ProxyDirContext instance pointing to the outside folder and I'm not sure whether that will work; its configuration process is rather involved.

Trying to override servlet path will not get you anywhere.

Upvotes: 2

cletus
cletus

Reputation: 625247

That's not a good idea.

Web containers or application servers can be deployed behind Web servers or you can simply use a Web server in conjunction with your container. Just put your static files under that and refer to them by absolute path.

There's really no need for this kind of hack (sorry but that's what it is).

Either that or simply deploy them with the Web app.

Upvotes: 0

Related Questions