Java Servlets session.getAttribute and setAttribute

javaservletssession

I was trying to make a counter for the get requests of each session and I finally made it, however, I have a question in order to get to the bottom of the logic how this works. Here is my code:

public class FirstServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
       final String COUNTER = "Counter";
    /**
     * @see HttpServlet#HttpServlet()
     */
    public FirstServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            HttpSession session = req.getSession();
            PrintWriter out = resp.getWriter();
            int count = 1;
            Integer i = (Integer) session.getAttribute(COUNTER);
            if(i != null){
                count = i.intValue() +1;
            }
            session.setAttribute(COUNTER, new Integer(count));
             out.println("<html>");
                out.println("<head>");
                out.println("<title>Session Counter</title>");
                out.println("</head>");
                out.println("<body>");
                out.println("Your session ID is <b>" + session.getId());
                out.println("</b> and you have hit this page <b>" + count
                    + "</b> time(s) during this browser session");
        }

Here are the questions:

Integer i = (Integer) session.getAttribute(COUNTER);
                if(i != null){
                    count = i.intValue() +1;
                }

Since I'm making Integer i and then casting it to integer, does this mean that no matter of the String value it will always have an int value of 0? (because COUNTER is of type String)

My second question is: why do I have to use session.setAttribute() after I get it in order to print the new value. My logic is the following. As we know each servlet is instantiated only once – I get the attribute (session.getAttribute(COUNTER)), check if i is different than null and then increment it, if I comment the setAttribute I'll not be able to see the new incremented value. Why do I have to set again in order to get the right value? When I press refresh I'm making a new get request and it takes the old value of COUNTER (for example 2), then we check if it is not null and increment it by 1. I don't get why I have to use session.setAttribute again…

Thanks!

Best Answer

First question: No. If the attribute is not in session, i will be null.

Second: This behavior is related to concept of immutability and understanding Java's concept of references.

Since sessions are storing Objects, your counter will become a reference to Integer object by autoboxing (so there's no need to create the Integer by hand). It is one of the immutable classes in JDK, and to change its value, You will need to create a new object reference, that's why it is required to update the object that is stored in session - because session still stores the reference address to old value.