views:

42

answers:

1

This should be relatively simple to do but I've yet to find a description of how to do it.

My setup is a simple web app that processes every request through a servlet (I'll call it MyEverythingServlet for this question). Here's a slightly modified version of my web.xml:

<servlet>
    <servlet-name>MyEverythingServlet</servlet-name>
    <servlet-class>blah.blah.blah.MyEverythingServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>MyEverythingServlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

Right now, the servlet is pretty simple and either does some work (when work.do is part of the path) and if a .txt file is specified in the path, we'll do some validation and then load the file and send the text as the response:

response.getOutputStream().print( content );

What I'd like to do is either:

  • Inside the servlet, if the request is a URL to a .jsp file, I'd like to be able to have the container interpret the JSP scriptlet parts/taglib stuff before I write the String to the response.
  • Change my web.xml to have it process .jsp files outside of MyEverythingServlet.
+3  A: 
  • Inside the servlet, if the request is a URL to a .jsp file, I'd like to be able to have the container interpret the JSP scriptlet parts/taglib stuff before I write the String to the response.

There's no direct API available which processes JSP files programmatically like that. In theory, you'd like to have the JSP in public webcontent and forward the request to the JSP. You can do this with RequestDispatcher#forward().

if (request.getServletPath().endsWith(".jsp")) {
    request.getRequestDispatcher(request.getServletPath()).forward(request, response);
} else {
    // Write "plain" to response as you did.
}

You may only want to do some checks on the correctness of the paths, but this should at least give you the generic idea. There is however a little problem: the servlet will be invoked recursively since it's mapped on /*. You'd rather replace this MyEverythingServlet by a Filter which just delegates the remnant of the job to the appserver's builtin default servlet. Having a Servlet to listen on /* is already a design-smell indication that it should have been a Filter from the beginning on ;)

  • Change my web.xml to have it process .jsp files outside of MyEverythingServlet.

You can't have a "negative" url-pattern in web.xml. Best what you can do is to let the servlet listen on a more specific url-pattern like *.txt or /static/* and keep the JSP files there outside.

BalusC
Are you suggesting I use filter and filter-mapping instead of servlet-mapping in my web.xml file? Then I'd have the filter look for *.jsp and do nothing for those requests (chain.doFilter() )? How would the Filter send non-JSP requests to the MyEverythingServlet?
Chris Williams
You can also do so (only if those non-JSP files are outside public webcontent and you're forced to use `FileInputStream` or so to read them). You should then map the servlet on a more specific `url-pattern` and dispatch the request using an URL matching this pattern (I'd in turn question the value of the Filter.. ;) ). But if those files are in public webcontent, then just continuing filter chain is enough. The servletcontainer's builtin default servlet will serve the non-JSP file up for you.
BalusC
Ok, I think the only piece I'm missing is how the Filter will forward the request on to the MyEverythingServlet.
Chris Williams
E.g. `request.getRequestDispatcher("/servletURL" + request.getServletPath()).forward(request, response);` whereby the `MyEverythingServlet` is mapped on `/servletURL/*` (change to your taste). But on the other hand, you can also just change the existing URL's to match this servlet without the need to have it passed through a filter :)
BalusC
Sorry, I should have added that the `getServletPath()` method can only be accessed in the `Filter` after downcasting the `ServletRequest` argument to `HttpServletRequest`. If you want a more complete URL (i.e. including root folders), you can also use `getRequestURI()`.
BalusC