Matthew
Matthew

Reputation: 8416

How to to basically and simply set up a Servlet to handle and pre-process JSP requests

I would like to have a Servlet handle all requests to JSP pages first. The Servlet will be used to set server side variables depending on the requested JSP.

For example, what I would like to achieve is given the url:example.com/index.jsp, the Servlet first handles the request by parsing out the requested JSP (index.jsp), sets variables that are specific to the requested index.jsp (using request.setAttribute) and then dispatches to the actual index.jsp (eg. /WEB-INF/index.jsp). The JSP will then have the correct variables it needs.

My problem so far is that I'm using "/*" as the mapping pattern for my Servlet. It handles the request, then uses requestDispatcher.forward("/WEB-INF/index.jsp") which ends up in an infinite loop since this matches the "/*" pattern as well.

How should my Servlet(s) handle the requested url? What should the I use as the mapping pattern(s) in web.xml?

Is there a standard setup for this? I'm just looking for a "best practices" way to set up pre-processing for all my JSPs.

Upvotes: 2

Views: 1313

Answers (1)

BalusC
BalusC

Reputation: 1108537

The /* is in first place a strange choice for a servlet URL pattern. This is normally exclusively to be used by filters. Servlets are by default namely also invoked on forwards and includes, but filters not. Using /* would completely override the container's builtin JspServlet which ought to be invoked on *.jsp during a forward.

Rather use a more specific URL pattern like /pages/*, /app/*, *.do, *.html, etcetera.

When using a prefix servlet mapping, like /pages/* and you would like to hide the extra path from the URL, then you should keep the prefix servlet mapping as is, put all other resources in a common path (usually it are only the static resources like CSS/JS/images) and create an additional filter which checks if it's a resource request and if so, then continue the chain or if not, then forward to the servlet. This does not change the URL. The servlet can in turn just safely forward to the JSP.

Here's an example assuming that your servlet is mapped on /pages/* and that all your (static) resources which should not be handled by the servlet are placed in /resources folder (you can just keep your JSPs in /WEB-INF, that part doesn't need to be changed; the forward wouldn't hit the filter anyway).

HttpServletRequest req = (HttpServletRequest) request;
String path = req.getRequestURI().substring(req.getContextPath().length());

if (path.startsWith("/resources/")) {
    chain.doFilter(request, response);
} else {
    request.getRequestDispatcher("/pages" + path).forward(request, response);
}

Finally just map the above filter on an URL pattern of /*.

See also:

Upvotes: 1

Related Questions