Search code examples
javaservletshttpsession

HttpSession attribute : Why is the attribute not updated


I am practicing a little bit with sessions and servlets. I have created a servlet to test it, and I have the next "doGet" method:

    @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
    PrintWriter out = resp.getWriter();
    HttpSession session = req.getSession();
    if(session.isNew()) {
        out.println("Welcome.");
    } else {
        out.println("Nice to see you again.");
    }
    Integer visits = (Integer)session.getAttribute("timesVisited");
    if (visits == null) {
        visits = new Integer(1);
        session.setAttribute("timesVisited", visits);
    } else {
        visits = visits + 1;
        session.setAttribute("timesVisited", visits);
    }
    out.println(" You have visited that servlet " + visits + " times.    ");
    out.println("<a href = \"" + resp.encodeURL("SessionServlet.do") + "\">" + "hola" +  "</a>");
    return;


}

What is wondering me, is that I need the line

session.setAttribute("timesVisited", visits);

to update the value of the "timesVisited" attribute on the session. If I comment that line, the value will be always 1 each time I call the servlet. I was expecting that, since the attribute objects are linked to the session, if I updated the value of the attribute in the servlet (as it happens in that example), it would just get the new value in the Session without me having to call "setAttribute" again.

Does anyone know what I am missing? I am sure it is something completely lame that I have not seen.

Thanks for your time.


Solution

  • When you do visits = visits + 1, you're assigning a new object to the visits reference, and the session keeps pointing at the older value:

    Before getting the attribute:

    session ---> Integer(1)
    

    After getting the attribute:

    session ---> Integer(1)
                    ^
    visits ---------|
    

    After visits = visits + 1

    session ---> Integer(1)
    
    visits ----> Integer(2)
    

    You wouldn't need to set the attribute again in the session is you used a mutable counter object, and did the following:

    Counter counter = (Counter) session.getAttribute("visits");
    counter.increment();
    

    Where increment() would do:

    this.value++;
    

    Java has such a class: AtomicInteger:

    AtomicInteger counter = session.getAttribute("visits");
    counter.incrementAndGet();