Java Server Pages: Session Tracking

Since HTTP is a stateless protocol, the web server cannot remember previous requests. Consequently, the web server cannot relate the current request with the previous one. This creates a problem for some applications that require a sequence of related request-response cycles. Examples include online examination systems, email checking systems, and banking applications. How does the server know how many questions you have answered so far or when you started the examination?

We shall use a simple application to demonstrate session tracking using different methods. In this application, the server initially dynamically generates an HTML file to display the integer 0, with two buttons captioned “prev” and “next”. If the user clicks on the next button, the server sends the integer next to the one displayed. Similarly, when prev button is clicked, the server sends the integer previous to the one displayed.

Note that each time the server receives a request, it has to remember the number it sent in the previous step. Let us now discuss the different methods used for session tracking.

1. Hidden fields

An HTML hidden field is created using the <input> tag, with the type attribute hidden. For example, the following creates a hidden field.

<input type=”hidden” name=”user” value=”monali” >

The interesting part about hidden fields is that web browsers do not display them, but send the name-value pair of each hidden field exactly like other input elements when the enclosing form is submitted. So, hidden fields may be used to send information back and forth between server and client to track sessions, without affecting the display. Hidden fields are ideal for applications that do not require a great deal of information.

Let us now implement the application mentioned, using hidden fields.

<%@page import=”java.util.*”%>

<html>

<head><title>Hidden field demo</title></head>

<body>

<%

int current = 0;

String last = request.getParameter(”int”);

String button = request.getParameter(”button”); if(button != null) {

if(button.equals(”next”))

current = Integer.parseInt(last) + 1; else

current = Integer.parseInt(last) – 1;

}

out.println(current);

%>

<br>

form name=”myForm” method=”post”>

<input type=”hidden” name=”int” value=”<%=current%>”>

<input type=”submit” name=”button” value=”prev”>

<input type=”submit” name=”button” value=”next”>

</form>

</body>

</html>

In this method, the JSP page uses a single hidden field in the generated HTML file named “int”. The value of this hidden field is the integer being sent currently. The hidden field, together with the two submit buttons captioned “prev” and “next”, are put in a form. So, the web browser receives an HTML file like this:

<html>

<head><title>Hidden field demo</title></head>

<body>

0

<br>

form name=”myForm” method=”post”>

<input type=”hidden” name=”int” value=”0”>

<input type=”submit” name=”button” value=”prev”>

<input type=”submit” name=”button” value=”next”>

</form>

</body>

</html>

The HTTP post method is used in the form and no action attribute is specified. When the user clicks any of the two submit buttons, the value of this hidden field (which is the integer currently displayed) is sent to the same JSP page behind the scene. The JSP page extracts this value and understands that this value was sent in response to the previous request. This way, the hidden field helps the JSP page to remember information sent earlier. It also determines the button whose click event generates this request. The JSP page can then easily calculate the value to be sent next, depending on the button clicked.

The advantage of this method is that it does not require any special support from the client’s side. Hidden fields are supported by all browsers and the underlying information propagation is absolutely transparent to the user.

Note that users can view the source code of the HTML page and consequently see the value of the hidden field. So, the JSP page should not pass sensitive information such as passwords in the hidden field.

2. URL Rewriting

This is another simple but elegant method to track sessions and is widely used. It does not require any special support from the web browser. Remember that HTTP allows us to pass information using HTTP URL. This method makes use of that concept. The session information is appended to the URL. Here is the solution using URL rewriting.

<%@page import=”java.util.*”%>

<html>

<head><title>URL rewriting demo</title></head>

<body>

<%

int last = 0;

String param = request.getParameter(”int”); if(param != null) last = Integer.parseInt(param);

out.println(last);

%>

<br>

<a href=”intUrl.jsp?int=<%=last-1%>”>prev</a>

<a href=”intUrl.jsp?int=<%=last+1%>”>next</a>

</body>

</html>

In this case, the JSP page generates and sets the URL to be called for the hyperlinks “prev” and “next”. For example, the web gets this HTML page for the first time:

<html>

<head><title>URL rewriting demo</title></head>

<body>

0

<br>

<a href=”intUrl.jsp?int=-1″>prev</a>

<a href=”intUrl.jsp?int=1″>next</a>

</body>

</html>

When a user clicks on the “prev” hyperlink, the integer that should be sent by the JSP page for this request is appended to the URL. The JSP page simply extracts this information and sends it back with the new URLs for those two hyperlinks. A similar sequence of events happen when a user clicks on the “next” button.

3. Cookies

This method requires support from the web browsers. In this method, session information is represented by a named token called cookie. The JSP page sends this cookie to the web browser. The browser must be configured properly to accept it. Upon receiving a cookie, the web browser installs it. This cookie is then sent back to the server with the subsequent requests. The JSP page can then extract session information from this cookie. This way, the server can identify a session.

By default, most browsers support cookies. However, due to security reasons, very often cookie support is disabled and in that case session management will not work correctly. The following is the JSP page for the application we discussed earlier.

<html>

<head><title>Cookie demo</title></head>

<body>

<%

int current = 0;

Cookie cookie = null;

Cookie[] cookies = request.getCookies();

if(cookies != null)

for(int i = 0; i < cookies.length;

i++) if(cookies[i].getName().equals(”last”)) cookie = cookies[i];

if(cookie != null) {

String button = request.getParameter(”button”); if(button != null) {

if(button.equals(”next”))

current = Integer.parseInt(cookie.getValue()) + 1; else

current = Integer.parseInt(cookie.getValue()) – 1;

}

}

response.addCookie(new Cookie(”last”, String.valueOf(current)));

out.println(current);

%>

<br>

form name=”myForm” method=”post”>

<input type=”submit” name=”button” value=”prev”>

<input type=”submit” name=”button” value=”next”>

</form>

</body>

</html>

The JSP page first looks for a cookie named “last”. If it finds the cookie, the value of the cookie is obtained using the getVaiue() method. Depending on the button clicked, the integer to be sent next is calculated and stored in the variable current. This integer, together with a new cookie with the name “last” having the current value set is sent to the web browser. However, if the JSP page does not find any cookie with the name “last”, which happens during the first time, it sends a new cookie having the value 0, which is the initial value of the variable current.

4. Session API

JSP technology (and its underlying servlet technology) provides a higher level approach for session tracking. The basic building block of this session API is the javax.servlet.http. HttpSession interface. The HttpSession objects are automatically associated with the client by the cookie mechanism. An HttpSession object is one that persists during a session, until it times out or is shutdown by the JSP page participating in this session.

In a JSP page, an HTTP session is created by default if it is not suppressed by setting the session attribute of the page directive to false as follows.

<%@ page session=”false” %>

This session can be accessed by the implicit object session. A JSP page may also create an HttpSession object explicitly, using the following method in HttpServletRequest.

HttpSession getSession(boolean create);

HttpSession getSession();

The first version takes a boolean parameter that indicates whether a new session has to be created if one does not exist. If the parameter is true, a new session is created if it does not exist. Otherwise, the existing session object is returned. If the parameter is false, it returns the existing session object if it exists, and null otherwise. The second version simply calls the first version with the parameter true.

In the HttpSession object, we can store and retrieve key-value pair using setAttribute(), getAttribute() , and getAttributes() methods.

Object getAttribute(String key);

Enumeration getAttributeNames();

void setAttribute(String key, Object value);

The return type of the getAttribute() method is Object. So you must typecast it to the required type of data that was stored with a key in the session object. If the key specified in the setAttribute() method does not already exist in the session, the specified value is stored with this key. Otherwise, the old value is overwritten with the specified value.

The JSP engine uses the cookie mechanism to keep track of sessions. A session object is associated with usually a long alphanumeric ID. This session ID is sent to the client as a cookie with the name jsessionid, when the client makes a request for the first time using the HTTP response header Set- Cookie, as follows:

Set-Cookie: JSESSIONID=g52d15acu325dlw532h234

For subsequent requests, the client sends this cookie back to the server using the HTTP request header Cookie as follows:

Cookie: JSESSIONID=g52d15acu325dlw532h234

The server can then identify that this request has come from the same client. However, if the client does not accept cookies, this mechanism fails. In that case, programmers may use the URL rewriting mechanism, where each URL must have the session ID appended. The JSP engine, on behalf of programmers, provides a straightforward mechanism to implement URL rewriting. The HttpServletResponse object provides methods to append this session ID automatically. These methods identify whether the client is configured to accept cookies. They append the session ID only if the client does not accept cookies.

java.lang.String encodeURL(java.lang.String);

java.lang.String encodeRedirectURL(java.lang.String);

The encodeRedirectURL() method is used for the sendRedirect() and encodeURL() method is used for the rest to create such URLs.

Here is the solution of our application using HttpSession API:

<%@page import=”java.util.*”%>

<html>

<head><title>Hidden field demo</title></head>

<body>

<%

int current = 0;

String last = (String)session.getAttribute(”last”);

if(last != null) {

String button = request.getParameter(”button”); if(button != null) {

if(button.equals(”next”))

current = Integer.parseInt(last) + 1; else

current = Integer.parseInt(last) – 1;

}

}

session.setAttribute(”last”, String.valueOf(current));

out.println(current);

%> <br>

<form name=”myForm” method=”post”>

<input type=”submit” name=”button” value=”prev”>

<input type=”submit” name=”button” value=”next”>

</form>

</body>

</html>

Source: Uttam Kumar Roy (2015), Advanced Java programming, Oxford University Press.

Leave a Reply

Your email address will not be published. Required fields are marked *