forwarding with RequestDispatcher after going through Java Filter

michauwilliam picture michauwilliam · Jan 20, 2012 · Viewed 8.6k times · Source

First of all let me describe what I'm trying to do, which I'm guessing is pretty simple. I have a website with users and want to restrict access to a view_profile.jsp page only to logged users. I have a filter mapped to:

<url-pattern>/auth/*</url-pattern>

which looks like this

        try {
        HttpSession session = ((HttpServletRequest)request).getSession();
        UserBean user = (UserBean)session.getAttribute("currentUser");
        if (user != null && user.isValid()){
            System.out.println("Filter: context -> " + ((HttpServletRequest)request).getContextPath()); //returns ""
            chain.doFilter(request, response);
        }
        else{
            ((HttpServletResponse)response).sendRedirect("/login.jsp"); //works fine
        }

This filter is run when on the index.jsp page user will click on a link:

<a href="./auth/view_profile?profile=${sessionScope.currentUser.username}">
//yeah, he will 'view' himself - it's just an example

which is suppose to take the user to the servlet mapped to ViewProfileServlet mapped to:

<url-pattern>/auth/view_profile</url-pattern>

which looks like that:

    try {
        String username = (String) request.getParameter("profile");

        // here is getting info from database and setting request attributes
        // works fine

                //response.sendRedirect("/view_profile.jsp");
                System.out.println("ViewProfileServlet: In context -> " + getServletContext().getContextPath()); // returns ""
                dis = getServletContext().getRequestDispatcher("/view_profile.jsp");
                // i've tried request.getRequestDispatcher. no difference
                System.out.println("ViewProfileServlet: forward to '/view_profile.jsp'");
                dis.forward(request, response);
            }

Which in turn should take the user to the /view_profile.jsp (in the root context, not in /auth) and work, which it doesn't. What happens is the ViewProfileServlet runs and the view_profile.jsp shows, although it seems that the context is still /auth because all the links on view_profile.jsp point to i.e localhost:8080/auth/some-page.jsp. Also, css files are not being loaded, they're not even requested (at least according to firebug), and page source shows 404 Glassfish Error where css's suppose to be.

I would greatly appreciate any help, it's the first time i'm even doing something in jsp and i'm completely lost here.

Answer

JB Nizet picture JB Nizet · Jan 20, 2012

A forward happens entirely at server-side. The browser doesn't know about it. When it sends a request to /auth/view_profile, and receives HTML from this response, he doesn't care if the HTML has been generated by a servlet, a JSP, both, or anything else. It reads the HTML and considers it comes from the path /auth/view_profile. All the relative path in the HTML are thus relative to /auth/view_profile.

It's far easier to use absolute paths to reference images, JS and CSS paths (and even other actions, most of the time). Just make sure to use the <c:url> tag to generate the URL, so that the context path of the web-app is prepended:

<script src="<c:url value='/js/myScript.js'/>" type="text/javascript"/>
                           ^-- the slash here makes the path absolute.