views:

93

answers:

3

I just started exploring Java Servlets and JSP and am a little confused about the sessions object. Inside a servlet I have this:

public class SampleServlet extends HttpServlet {

    public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws IOException {

        HttpSession session = request.getSession(true);
        session.setAttribute("_session", "_value");
                response.sendRedirect("page2.jsp");         
        }
}

Now, inside page2.jsp, there is a session object as well, but when I do this

<%
out.print(session.getAttribute("_session"))
%>

it does not seem to get the value (as if it is not set). I tried setting a boolean attribute to true but in the jsp page it returns a false. Can someone tell me the right way of doing this? As to what I am trying to do, I want to share some session variables.

+1  A: 

Assuming your container supports it, use EL!

Java side:

HttpSession session  = request.getSession(true);
session.setAttribute("foo", "bar");

JSP side:

<html>
    ...
    <body>
        ...
        <p>${foo}</p>
        ...
    </body>
</html>

And that will give you a paragraph containing the string bar.

Matt Ball
Doesn't explain the original problem, though...
skaffman
@Bears: +1 for EL. Just beginning to hear some Java side technologies :)
Legend
@skaffman - is the original problem (redirect not preserving session info) GAE-specific? I actually use session attributes (vs request attributes) when I want to preserve information across a redirect, using JBoss+Tomcat.
Matt Ball
It looks like it, yes
skaffman
+1  A: 

Use request.getRequestDispatcher().forward() instead of response.sendRedirect();

So your code would be:

 HttpSession session = request.getSession(true);
 session.setAttribute("_session", "_value");
 request.getRequestDispatcher("page2.jsp").forward();     

Basically, response.sendRedirect() does not preserve session info, so it's not there when the jsp gets it. request.forward() does preserve the session.

See http://www.coderanch.com/t/170618/java-Web-Component-SCWCD/certification/sendRedirect-Vs-requestdispatcher-forward

Matthew Flynn
The last line is syntactically invalid and he's setting a session attribute, so it should be there in the redirected request.
BalusC
Oops, I put the arg in the wrong place. Updated
Matthew Flynn
@Matthew: Awesome! Thanks... It works now... I had to change that `forward` to `forward(request, response)` though.
Legend
@Legend: That might be container dependent. Your initial approach works fine on both Tomcat 6 and Glassfish 3 here. I tested it. That would be a bug in container used by Google Appengine.
BalusC
@BalusC: Thanks for the clarification. I will raise a bug report with Google as I can reproduce it.
Legend
+1  A: 

Although not the best approach (I'd rather use EL ${_session} than a scriptlet), this should work fine. Your problem lies somewhere else. Are you running the code you think you're running? How are you compiling and deploying the code? Didn't you trim too much off from the given example? The session is namely domain and context dependent, if you redirect to a different domain and/or context, then a new session would be created. Also, the session is backed by a cookie, does the browser have cookies enabled? Else you'll have to use HttpServletResponse#encodeRedirectURL() to append the session identifier to the redirect URL.

response.sendRedirect(response.encodeRedirectURL("page2.jsp"));

Update: to debug if it's really the same session, do in the servlet:

System.out.println("Session ID: " + session.getId());

and in the JSP:

<p>Session ID: ${pageContext.session.id}</p>

Also installing a HTTP header tracker like Firebug's Net panel may bring new insights. The HTTP response should include a Set-Cookie header with the session ID and the subsequent HTTP requests should include a Cookie header with the same cookie name/value, usually JSESSIONID with a long hex value like as on this screenshot.


Update 2: since I was suprised because a forward apparently fixes this issue, I tried to reproduce this on Tomcat 6 and Glassfish 3, but this approach works perfectly on the both servers. So I suspect a bug in the container used by Appengine, that it is not setting the cookie correctly during the redirect.

As evidence, here's a screen which proves that Glassfish is setting the cookie by Set-Cookie and firing the redirect by Location:

alt text

BalusC
@BalusC: I am using Google App Engine framework. Writing a few servlets and jsp files inside the project that Eclipse created.
Legend
@BalusC: Just tried your approach. It seems to behave the same way.
Legend
@BalusC: +1 for your time.
Legend