Previous |
Next |
One of the essential features of the HTTP protocol is that it is “stateless”. This means that when a web browser makes a request for a resource from a web server, the server “forgets” about the requesting machine at the end of the transaction. The benefit of this is that a server can be relatively simple and can serve up vast amounts of information without having to track each machine between requests.
This gives a big performance advantage by comparison with technologies that require a user to log in and for the server to “maintain state”. However it comes with the significant disadvantage that HTTP does not support a continuous conversation, i.e. each request is treated in isolation to every other request. This means it is not possible to design a shopping cart system in “pure HTTP” because although you could request an item from a page displaying inventory, as soon as you made the next request the server would not know about your previous request.
If it was not possible to overcome this inherent problem the World Wide Web would be a footnote in the history of technology. The standard way of maintaining state between an individual web browser and a web server is the concept of a session. There are several ways of creating a session but different web programming technologies (ASP, JSP, PHP) all use a very similar approach. To become familiar with using sessions you have to forget most what you might know about using standard Java variables (fields and method local variables) and get used to using session based attributes. Once you become familiar with session based attributes you can mostly forget that they require a session to sustain state.
The object that wraps up the features of a session is an instannce of HttpSession and within a servlet an instance can be obtained by calling the HttpServletRequest getSession() method. The object returned can be used to store Java variables. As a moderate inconvenience these are always stored with the data type of Object but they can be cast back to the original type as required. That is how sessions appear to a programmer but it is useful to look at how sessions are actually implemented.
When a web browser makes a request from the server the server generates a unique id that is returned to the browser. An example of a unique id might look something like
6AD095E84932FFD37E02CA74870CE71D
The browser then stores this id and upon making the next request the id is sent to the server so it can associate each successive request. The most common way of storing this “conversational state” is for the server to generate a cookie or a small piece of text that is transmitted with the header information of the page returned to the browser. Cookie technology was invented by Netscape corporation, one of the first very popular browsers in the early days of the web.
The servlet specification mandates that the cookie used to maintain sessions be called JSESSIONID. It is perfectly possible to maintain state by hand coding your own state by writing code to manually store and retrieve cookies. Having done that task myself using the Perl programming language I recommend you be grateful for the servlet session mechanism and never try to maintain state through your own code.
Some users have had concerns that cookies bring privacy issues, but they are generally benign and bring the huge benefit of allowing a browser to establish a session with a server. If a browser has cookies disabled or does not support cookies it is possible to record the state by a process known as URL re-writing where the unique id is appended to the browser URL, which can thus be read by the server. Using sessions with JSP pages is fairly transparent as by default JSP pages are session enabled and provide the implicit session object, which can be manipulated within Java code. A session does not automatically die when a user shuts down their browser, but is dependent on the session timeout. So for example you might want to maintain a session between logins on the state of a users shopping cart.
The methods for storing and retrieving data from a session are setAttribute and getAttribute. Note that objects stored via set and getAttribute are only available to the client that started the session, i.e. the unique id of the session reserves the data for a single client (usually a single user with a web browser).
Note that attribute data is stored with a type of Object and must be cast back to the required type before being used. As should be implied from this, an attribute cannot be a primitive type, but you can of course wrap up a primitive within a wrapper class.
The following code shows how you can store a String array within a session in one JSP and then retrieve the values from the array in another JSP>
<html>
<body>
<h2>Start Session</h2>
<%
String[] fruit = {"apple","orange","pear"};
session.setAttribute("fruit_at",fruit);
%>
</body>
</html>
Note how the code uses the implicit session object. In a servlet you would have to write a line of code to retrieve an instance of session. The setAttribute method takes the form of a key value pair. The first parameter is the name of the attribute and the second is the object that is to be stored.
The following code retrieves the attribute and prints out the values of the array.
<html>
<body>
<%
String[] fruit = (String[]) session.getAttribute("fruit_at");
for(String s : fruit){
out.print(s +" ");
}
%>
</body>
</html>
Note how the value retrieved from the session is cast back to its original type, in this case String array.
There is a general rule that display code and procedural code should not be mixed up. If they can be kept separate then programmers can deal with the code and designers can deal with the layout. If a page starts to include scriptlet code this rule begins to be broken. One way of moving code out of the HTML is with the useBean tag. By using a single tag within a JSP an instance of a JavaBean is made available within the page and its methods can be accessed with minimal cluttering of the page. For this demonstration I will create a bean called Person which has methods for getFirstName and getLatName.
package com.examulator;
public class Person {
private String firstName="joe";
private String lastName="soap";
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}
That JavaBean can be used within a JSP as follows
<jsp:useBean id="person" type="com.examulator.Person" class="com.examulator.Person" scope="session" /> <html> <% out.print(person.getFirstName()); %> </html>
If you compile and run that page you will find it outputs the default firstName of joe to the browser. The type attribute can be considered like the reference type in a plain old Java class whilst the class is the type of the actual object. Note the use of a scriptlet to get at the firstName property in that example. The idea of the useBean tag was to get away from using scriptlets and the JSP specification provides a the setProperty and getProperty tags to help avoid using a scriptlet. Thus instead of the complete scriptlet code you can use the following.
<jsp:useBean id="person" type="com.examulator.Person" class="com.examulator.Person" scope="session" /> <html> <jsp:getProperty name="person" property="firstName"/> </html>
Other sources
Maintaining client state by Sun
http://java.sun.com/j2ee/1.4/docs/tutorial/doc/Servlets11.html#wp64744
Session tracking by Marty Hall
http://www.apl.jhu.edu/~hall/java/Servlet-Tutorial/Servlet-Tutorial-Session-Tracking.html
API Docs to the HttpSession
interface
http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/http/HttpSession.html
Cookies according to Wikipedia
http://en.wikipedia.org/wiki/HTTP_cookie
Previous |
Next |