JSP session(会话)跟踪

  • 会话跟踪

    在本章中,我们将讨论JSP中的会话跟踪。HTTP是一种“无状态”协议,这意味着每次客户端检索网页时,客户端都会打开与Web服务器的单独连接,并且服务器不会自动保留先前客户端请求的任何记录。
  • 维护Web客户端和服务器之间的会话

    现在让我们讨论一些选项,以维护Web客户端和Web服务器之间的会话-
    cookie
    Web服务器可以将唯一的会话ID作为cookie分配给每个Web客户端,对于来自客户端的后续请求,可以使用接收到的cookie来识别它们。这可能不是一种有效的方法,因为浏览器有时不支持cookie。不建议使用此过程来维护会话。
    隐藏的表单域
    Web服务器可以发送隐藏的HTML表单字段以及唯一的会话ID,如下所示-
    
    <input type = "hidden" name = "sessionid" value = "12345">
    
    此条目意味着,提交表单后,指定的名称和值将自动包含在GET或POST数据中。每次Web浏览器发送回请求时,session_id值都可用于跟踪不同的Web浏览器。这可能是跟踪会话的有效方法,但是单击常规(<a href...>)超文本链接不会导致表单提交,因此隐藏的表单字段也不能支持常规会话跟踪。
    URL重写
    您可以在每个URL的末尾附加一些额外的数据。此数据标识会话;服务器可以将该会话标识符与其已存储的有关该会话的数据相关联。例如,使用http://cainiaoya.com/file.htm;sessionid=12345,将会话标识符附加为sessionid = 12345,可以在Web服务器上访问该会话标识符以标识客户端。URL重写是维护会话的一种更好的方法,并且在浏览器不支持cookie时适用于它们。这里的缺点是,尽管页面是一个简单的静态HTML页面,但您必须动态生成每个URL才能分配会话ID。
  • 会话(session)对象

    除了上述选项外,JSP还利用Servlet提供的HttpSession接口。该界面提供了一种识别用户的方法。
    • 一页请求或
    • 访问网站或
    • 存储有关该用户的信息
    默认情况下,JSP启用了会话跟踪,并且自动为每个新客户端实例化一个新的HttpSession对象。禁用会话跟踪需要通过将page指令session属性设置为false来显式关闭它-
    
    <%@ page session = "false" %>
    
    JSP引擎通过隐式session对象向JSP作者公开HttpSession 对象。由于session对象已经提供给JSP程序员,程序员可以立即开始而没有任何初始化或存储和检索从对象数据的getSession() 。
    这是通过会话对象可用的重要方法的摘要-
    方法 描述
    public Object getAttribute(String name) 在此会话中,此方法返回与指定名称绑定的对象;如果该名称下未绑定任何对象,则返回null。
    public Enumeration getAttributeNames() 此方法返回一个String对象的Enumeration,其中包含绑定到此会话的所有对象的名称。
    public long getCreationTime() 此方法返回创建此会话的时间,以格林尼治标准时间1970年1月1日午夜以来的毫秒数为单位。
    public String getId() 此方法返回一个字符串,其中包含分配给该会话的唯一标识符。
    public long getLastAccessedTime() 此方法返回客户端最后一次发送与此会话相关联的请求的时间,以格林尼治标准时间1970年1月1日午夜以来的毫秒数为单位。
    public int getMaxInactiveInterval() 此方法返回servlet容器使该会话在客户端访问之间保持打开状态的最大时间间隔(以秒为单位)。
    public void invalidate() 此方法使该会话无效,并取消绑定到该会话的任何对象。
    public boolean isNew() 如果客户端尚不知道会话或客户端选择不加入会话,则此方法返回true。
    public void removeAttribute(String name) 此方法从此会话中删除与指定名称绑定的对象。
    public void setAttribute(String name, Object value) 此方法使用指定的名称将对象绑定到此会话。
    public void setMaxInactiveInterval(int interval) 此方法指定客户端请求之间servlet容器使该会话无效之前的时间(以秒为单位)。
  • 会话跟踪示例

    本示例说明如何使用HttpSession对象找出会话的创建时间和上次访问时间。如果一个新的会话尚不存在,我们将其与该请求相关联。
    
    <%@ page import = "java.io.*,java.util.*" %>
    <%
       // 获取会话建立的时间
       Date createTime = new Date(session.getCreationTime());
       
       //获取最后访问这个页面的时间
       Date lastAccessTime = new Date(session.getLastAccessedTime());
    
       String title = "Welcome Back to my website";
       Integer visitCount = new Integer(0);
       String visitCountKey = new String("visitCount");
       String userIDKey = new String("userID");
       String userID = new String("ABCD");
    
       // 检查这是否是您网页上的新用户。
       if (session.isNew() ){
          title = "Welcome to my website";
          session.setAttribute(userIDKey, userID);
          session.setAttribute(visitCountKey,  visitCount);
       } 
       visitCount = (Integer)session.getAttribute(visitCountKey);
       visitCount = visitCount + 1;
       userID = (String)session.getAttribute(userIDKey);
       session.setAttribute(visitCountKey,  visitCount);
    %>
    
    <html>
       <head>
          <title>Session Tracking</title>
       </head>
       
       <body>
          <center>
             <h1>Session Tracking</h1>
          </center>
          
          <table border = "1" align = "center"> 
             <tr bgcolor = "#949494">
                <th>Session info</th>
                <th>Value</th>
             </tr> 
             <tr>
                <td>id</td>
                <td><% out.print( session.getId()); %></td>
             </tr> 
             <tr>
                <td>Creation Time</td>
                <td><% out.print(createTime); %></td>
             </tr> 
             <tr>
                <td>Time of Last Access</td>
                <td><% out.print(lastAccessTime); %></td>
             </tr> 
             <tr>
                <td>User ID</td>
                <td><% out.print(userID); %></td>
             </tr> 
             <tr>
                <td>Number of visits</td>
                <td><% out.print(visitCount); %></td>
             </tr> 
          </table> 
       
       </body>
    </html>
    
    现在,将上面的代码放入main.jsp中,并尝试访问http://localhost:8080/main.jsp。一旦运行URL,您将收到以下结果-
    现在,尝试第二次运行相同的JSP,您将收到以下结果。
  • 删除会话数据

    完成用户的会话数据后,您可以有几种选择-
    • 删除特定属性 - 您可以调用公共void removeAttribute(String name)方法来删除与特定键关联的值。
    • 删除整个会话 - 您可以调用public void invalidate()方法来丢弃整个会话。
    • 设置会话超时 - 您可以调用public void setMaxInactiveInterval(int interval)方法来分别设置会话超时。
    • 注销用户 - 支持Servlet 2.4的服务器,您可以调用logout将客户端从Web服务器注销,并使属于所有用户的所有会话无效。
    • web.xml配置 - 如果使用的是Tomcat,则除了上述方法外,还可以按以下方式在web.xml文件中配置会话超时。
    
    <session-config>
       <session-timeout>15</session-timeout>
    </session-config>
    
    超时以分钟表示,并覆盖默认超时(在Tomcat中为30分钟)。Servlet中的getMaxInactiveInterval()方法以秒为单位返回该会话的超时时间。因此,如果您的会话在web.xml中配置了15分钟,则getMaxInactiveInterval()返回900。