honzeland

记录点滴。。。

常用链接

统计

Famous Websites

Java

Linux

P2P

最新评论

Managing HttpSession Objects

zz: java.sys-con.com

Java servlet technology provides developers with functionality, scalability, and portability that can't be found in other server-side languages. One feature of the Java servlet specification that's commonly used, and sometimes misused, is the HttpSession interface. This simple interface allows you to maintain a session or state for Web site visitors.

In my previous article ("Introduction to Session Management," [JDJ, Vol. 7, issue 9]), I introduced you to session management and the HttpSession interface. In that article, we walked through using the HttpSession API to create, use, and destroy session objects for Web site visitors. The next step is to better understand how to manage the sessions and those objects in a session. This article will help you achieve this by helping you understand the following concepts:

  • Code-based session management through listeners
  • Proper design of the session and the objects it contains
  • Controlling what is in the session and why it's there
  • Session persistence
  • Memory management
The Java APIs discussed in this article are from Sun's Java Servlet 2.3 specification.

Listeners
A listener is an object that's called when a specified event occurs. There are four listener interfaces that allow you to monitor changes to sessions and the objects that are in those sessions:

  • HttpSessionListener
  • HttpSessionBindingListener
  • HttpSessionAttributeListener
  • HttpSessionActivationListener
Figure 1 provides a method summary for each of the listener interfaces. The implementing class that you write will override these methods to provide the functionality you need.

HttpSessionListener
The HttpSessionListener interface is used to monitor when sessions are created and destroyed on the application server. Its best practical use would be to track session use statistics for a server.

The use of HttpSessionListener requires a configuration entry in the deployment descriptor, or web.xml file, of the application server. This entry points the server to a class that will be called when a session is created or destroyed. The entry required is simple. All you need is a listener and listener-class element in the following format. The listener-class element must be a fully qualified class name.

<listener>
<listener-class>package.Class</listener-class>
</listener>

As you can see in Figure 1, the class that implements this listener can override two methods: sessionCreated() and sessionDestroyed(). These methods will be notified when the server creates or destroys a session.

These methods take an HttpSessionEvent object as a parameter. HttpSessionEvent is simply a class that represents notifications of changes to the Web application's sessions. HttpSessionEvent has one method, getSession(), that returns the HttpSession object that's been modified.

HttpSessionBindingListener
The HttpSessionBindingListener interface is implemented when an object needs to be notified if it's being bound to a session or unbound from a session.

This interface has two methods, valueBound() and valueUnbound(), that are notified when the status of the object has changed (see Figure 1).

These methods have an HttpSessionBindingEvent parameter that can be used to retrieve the session that the object was bound to and the name it was given in the session. In Figure 2, you can see the methods of this object that are used to get the name that's assigned to the object, the session it's bound to, and the actual object.

HttpSessionAttributeListener
The HttpSessionAttributeListener interface is used to monitor changes to attributes in any session on the server. This can be useful when you know the name assigned to a specific object that gets put into the session and you want to track how often it's being used.

As with HttpSessionListener, HttpSessionAttributeListener also requires an entry in the deployment descriptor for the server. This entry tells the server which class to call when an attribute in a session has changed.

The HttpSessionAttributeListener interface has three methods - attributeAdded(), attributeRemoved(), and attributeReplaced(). These methods, shown in Figure 1, are called by the server when attributes of a session are changed.

HttpSessionActivationListener
The final listener, HttpSessionActivationListener, is implemented when an object needs to know if the session that it's bound to is being activated or passivated (moved). You would come across this scenario if your session is being shared across JVMs or your server is persisting the session in a database or file system.

This interface, displayed in Figure 1, has two methods that are overridden by the implementing class: sessionDidActivate() and sessionWillPassivate(). These methods are called when the status of the session in a JVM is changed.

Session Persistence
Today's J2EE-compliant servers allow for fault-tolerance and failover to provide support in the event that a server suddenly becomes unavailable because of hardware, software, or network failure. This support is usually provided by allowing two or more application servers, often called a cluster, to run together and provide backup support for each other. If one server fails, the others pick up the requests and continue on as if nothing happened. This allows your Web site visitors to keep going without interruption.

A proxy server is usually used in front of the application servers. This server is responsible for directing each HTTP request to the appropriate server. The proxy server can be set up to ensure that the server receiving the first request from a user will continue to receive all subsequent requests from that user. This means that a session created for the user on the application server will continue to be available for that user. If the server suddenly fails, there has to be a system in place to allow the session to continue on without it.

Session persistence allows the session contents to be saved outside the application server so that other servers can access it. Figure 3 shows the relationship between the persisted session data and the application servers that access it. In this figure, you see a client accessing a Web site's HTTP server. The HTTP server is forwarding requests for application resources to one of the application servers through the use of a proxy server. The application servers are persisting the session data in an external form.

There are four types of session persistence:

  1. Memory persistence (one server or a cluster of two or more)
  2. File system persistence
  3. Database persistence
  4. Cookie persistence
Every application server will handle session persistence differently and all servers may not support all types of persistence. Objects that are placed in the session must be serializable for persistence to work.

Memory Persistence
In most cases, a single standalone server will store sessions in memory. This allows for fast retrieval and update of the information. It also means that the session information will be lost when the server is shut down. This is usually the default configuration on most application servers. Memory persistence can be used when two or more servers need to share the session information. The application servers can be configured to share any changes made to the session so that the information is available on multiple servers. This redundancy of the session information helps the cluster preserve the session during a failure.

File System Persistence
File system persistence can be used to serialize any objects that are in the session. The object contents are placed in a file on the server. The location of the files created is configurable; however, the files must be accessible by all the servers in the cluster. The speed at which the file system is accessed can be a factor in the performance of your Web site. A slow disk drive, for example, would result in a delay as data is read from or written to the file.

Database Persistence
Database persistence can be used to provide a central data store for the session contents. Each application server in the cluster must be able to access the database. When sessions are modified, the changes are immediately persisted in the database. A data source is usually set up for JDBC persistence and the connections are pooled. This provides a quicker response. There's also the issue of database failover, which would be addressed at the database level of the system.

Cookie Persistence
The fourth type of session persistence, cookie persistence, is so ineffective and insecure that it doesn't deserve consideration when designing a fail-safe system. Cookie persistence, as the name implies, persists session data by storing the session information in browser cookie(s). There's a limitation on data handling because cookies store only text, not objects, and the amount of data that can be transmitted in a cookie is limited. There's also the fact that cookies transmit data back and forth between the client and the server. This prevents you (at least it should) from saving sensitive information, like a social security number. This type of persistence should be used in only the smallest of Web sites, and only if there's a good reason not to store the session in memory.

The most common type of persistence is database persistence. It provides an efficient way of saving session data and it's usually fairly easy to set up on the application server. Memory persistence in a cluster is also easy to use, if your application server supports it. The only drawback is that sessions can sometimes hold large amounts of data. Storing the session in memory reduces the amount of memory available to the other processes on the server. File system persistence can be slow at times and the file system may not always be accessible to multiple servers.

Watching the Session Size
As you and your fellow employees work on a Web application, you may notice that more and more objects are being thrown into the session, often "for convenience" or "just temporarily." The session becomes a quick catch-all for any information you need to get from your servlets to your JSPs. The HttpSession interface makes sessions easy to use, which can lead to the session being overused. This is a concern because the session takes up space. In most cases that would be memory space. In other cases, it could be database or file system space. In all cases, it means more work for the server and more work for the programmers to manage what is there.

Although the session is convenient because it's accessible from every servlet or JSP, it's not always the best place to put information. Most of the data that's retrieved for display in a Web application will only be used on one page. Instead of putting the information into the session scope, use the request scope and then forward the request from the servlet to the JSP. This causes the objects to be destroyed after the request has ended, which is after the data is displayed by the JSP. If you put the objects into the session, you would either have to remove them in your code or leave them there. Leaving objects in the session is not a good idea because you're using up valuable resources for no reason. This becomes even more of an issue when your Web site has hundreds or thousands of visitors, all of whom have a session that's loaded with objects.

Some objects should be stored in the session. Objects that may be needed over and over again as a user moves through a Web site are those that should be put into the session. Anything that needs to exist longer than one request can be stored in the session, as long as these objects are removed as soon as they're no longer needed.

Considerations for Managing Sessions
When working with sessions, there are a few things to consider before designing or redesigning a Web application:

  • Are sessions needed in the application?
  • How long should the session be inactive before timing out?
  • Are all the objects in the session serializable?
  • Are the objects being bound to the session too large?
  • Do the objects that are in the session really need to be there?
A Need for Sessions
If you have unique users on a Web site and need to know who they are or need to get specific information to them, such as search results, then you should be using sessions. If you follow the guidelines set here, there's no reason not to use the HttpSession interface that Java provides. It's easy to use, flexible, secure, and it helps you to build a better Web site.

There's another architecture that deals with maintaining state for a client. Instead of relying on the HttpSession interface, state for clients can be maintained within Enterprise JavaBeans (EJBs). The EJB architecture takes the business logic for an application and places it in components or beans. A session bean is a type of EJB that exists for a given client/server session and provides database access or other business logic, such as calculations. Session beans can be stateless or they can maintain the state for a client, very much like an HttpSession object.

There is still some debate over where the state for a Web site visitor should be maintained. The best design for the application at this time is to continue using the HttpSession object for maintaining the state of the presentation layer of the Web application and to use stateful EJBs to maintain the state of the business logic and data layer. There are many other factors that should be considered with EJBs, one being the better performance of stateless beans over those that maintain state. These issues, which are outside the scope of this article, should be considered carefully when architecting an application.

Session Timeout
By default, on most servers the session is set to expire after 30 minutes of inactivity. The amount of time can be configured in the deployment descriptor of the Web application. The HttpSession API also provides a setMaxInactiveInterval() method that you can use to specify the timeout period for a session. The getMaxInactiveInterval() method will return this timeout value. The value given is in seconds.

The length of time will vary depending on what your visitors are doing on your site. If they're logging in to check their account balance, a shorter session timeout period can be used because it doesn't take long for a person to read a couple of numbers. If, on the other hand, the user is logging in to read large amounts of data, you need to be sure that you provide enough time for the user to do what he or she wants without being logged out. If the user is constantly navigating through your site, the session will last indefinitely.

Implement Serializable
It's important to make sure that all objects placed in the session can be serialized. This may not be an issue if you know that your Web application will not run in a cluster, but it should still be done anyway. What happens if your Web site grows too big for one server and you suddenly have to move to two? If you implement Serializable in your code now, you won't have to go back and do it later.

Keep It Simple
You should design objects that are going to be placed into a session so that they're not too big and don't contain unnecessary information. A JavaBean that contains a customer's name, address, phone number, e-mail address, credit card numbers, and order history should not be placed into the session if you're only going to use the object to get the customer's name.

Session Contents
When you're working on a Web site, it's important to know which objects are in the session and why they're needed. The size of the session should be kept as small as possible. If you're building a new Web site, work out ahead of time what goes in the session, why it's there, and where it gets removed. If you're redesigning an existing site, this may be a little tougher, especially when you have hundreds of servlets and JSPs to deal with. In this case, try implementing an HttpSessionAttributeListener to get an idea of what is going into the session. With this information, you may be able to better manage your sessions.

Conclusion
Hopefully this article helped you to better understand the design issues involved in using the HttpSession interface. Java provides a more robust session implementation than other languages. It's because of this power and flexibility that you must take the time to properly lay out the use of the session. A well-designed session will help make a Web application better for the programmers and the users.

References

  • Hall, M. (2002). More Servlets and JavaServer Pages. Prentice Hall PTR.
  • Java Servlet Technology: http://java.sun.com/products/servlet
  • Enterprise JavaBeans Technology: http://java.sun.com/products/ejb
  • Java BluePrints (J2EE): http://java.sun.com/blueprints/guidelines/ designing_enterprise_applications


  • 另外,还有一些收集的材料
    关于HttpSession的误解实在是太多了,本来是一个很简单的问题,怎会搞的如此的复杂呢?下面说说我的理解吧:
    1、HTTP协议本身是“连接-请求-应答-关闭连接”模式的,是一种无状态协议(HTTP只是一个传输协议);
    2、Cookie规范是为了给HTTP增加状态跟踪用的(如果要精确把握,建议仔细阅读一下相关的RFC),但不是唯一的手段;
    3、所谓Session,指的是客户端和服务端之间的一段交互过程的状态信息(数据);这个状态如何界定,生命期有多长,这是应用本身的事情;
    4、由于B/S计算模型中计算是在服务器端完成的,客户端只有简单的显示逻辑,所以,Session数据对客户端应该是透明的不可理解的并且应该受控于服务端;Session数据要么保存到服务端(HttpSession),要么在客户端和服务端之间传递(Cookie或url rewritting或Hidden input);
    5、由于HTTP本身的无状态性,服务端无法知道客户端相继发来的请求是来自一个客户的,所以,当使用服务端HttpSession存储会话数据的时候客户端的每个请求都应该包含一个session的标识(sid, jsessionid 等等)来告诉服务端;
    6、会话数据保存在服务端(如HttpSession)的好处是减少了HTTP请求的长度,提高了网络传输效率;客户端session信息存储则相反;
    7、客户端Session存储只有一个办法:cookie(url rewritting和hidden input因为无法做到持久化,不算,只能作为交换session id的方式,即a method of session tracking),而服务端做法大致也是一个道理:容器有个session管理器(如tomcat的 org.apache.catalina.session包里面的类),提供session的生命周期和持久化管理并提供访问session数据的 api;
    8、使用服务端还是客户端session存储要看应用的实际情况的。一般来说不要求用户注册登录的公共服务系统(如google)采用 cookie做客户端session存储(如google的用户偏好设置),而有用户管理的系统则使用服务端存储。原因很显然:无需用户登录的系统唯一能够标识用户的就是用户的电脑,换一台机器就不知道谁是谁了,服务端session存储根本不管用;而有用户管理的系统则可以通过用户id来管理用户个人数据,从而提供任意复杂的个性化服务;
    9、客户端和服务端的session存储在性能、安全性、跨站能力、编程方便性等方面都有一定的区别,而且优劣并非绝对(譬如TheServerSide号称不使用HttpSession,所以性能好,这很显然:一个具有上亿的访问用户的系统,要在服务端数据库中检索出用户的偏好信息显然是低效的,Session管理器不管用什么数据结构和算法都要耗费大量内存和CPU时间;而用cookie,则根本不用检索和维护session数据,服务器可以做成无状态的,当然高效);
    reply1:
    不过我们也不能在session里面放入过多的东西
    一般来说不能超过4K
    太多了
    对系统资源是一个很严重的浪费
    reply2:
    4K已是很大的一个数字了。
    我一般喜欢写一个类。封装用户登陆后的一些信息。
    然后把这个类放在session中,取得直接用类的方法取相关信息,

    posted on 2008-05-21 15:49 honzeland 阅读(292) 评论(0)  编辑  收藏 所属分类: Java


    只有注册用户登录后才能发表评论。


    网站导航: