Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Servlet's sendRedirect() kills my session attributes

I am working on a webapp in WinXP, Eclipse Indigo and Google web plugin.

I have a simple form that takes a value from user (e.g email) , passes it to a servlet named SignIn.java that processes it and saves the email value to the session. The SignIn code is very simple , here is what its doGet mostly does:

String email = req.getParameter("email");   //getting the parameter from html form
...
...
HttpSession session = req.getSession();     //create a new session
session.setAttribute("email", email);

So far so good, I've verified that the values aren't null at this point. Now comes the problem, I want to redirect to another servlet (ShowOnline.java) that needs to do some more processing. When I write

resp.sendRedirect(resp.encodeRedirectURL("/ShowOnlineServlet")); 

ShowOnline gets null session values (the same email attribute I saved a second before is now null)

When I write

getServletConfig().getServletContext().getRequestDispatcher("/ShowOnlineServlet");

everything is OK, the email attribute from before isn't null!

What is going on? sendRedirect() just makes your browser send a new request, it shouldn't affect the session scope. I have checked the cookies and they are fine (it is the same session from before for sure since it is the first and only session my webapp creates and furthermore I even bothered and checked the sesison ID's and they're the same on both requests).

Why would there be a difference between sendRedirect() and forward()? The easy solution would be to use forward() but I want to get to the bottom of this before I just let go , I think it is important for me to understand what happened. I'm not sure I like the idea of not knowing what's going on on such basic concepts (my whole webapp is very simple and basic at this point since I'm a beginner).

Any thoughts ideas or suggestions would be warmly welcome !

like image 419
Joel Blum Avatar asked Nov 06 '11 19:11

Joel Blum


1 Answers

If your SignIn servlet is only saving a request parameter (email), then you could also replace the servlet with a filter, e.g. SignInFilter.

SignInFilter would contain the same logic as your SignIn servlet (copying the email from the request parameters to the session), but would call the next item in the chain (which will be your ShowOnline servlet) instead of doing any redirect/forward.

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 
    throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;
    HttpSession session = request.getSession();

    String email = req.getParameter("email");
    session.setAttribute("email", email);

    chain.doFilter(req, res); // continue to 'ShowOnline'

}

Set up your form to POST to the ShowOnline servlet instead, and configure your new SignInFilter to execute before ShowOnline (servlet mapping omitted below for brevity).

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">

    <filter>
        <filter-name>SignInFilter</filter-name>
        <filter-class>com.example.SignInFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>SignInFilter</filter-name>
        <url-pattern>/ShowOnline</url-pattern>
    </filter-mapping>
</web-app>
like image 105
James Bassett Avatar answered Sep 18 '22 14:09

James Bassett