4.3 session对象

在Web开发中,session对象同样占据着极其重要的位置,在开发中它是一个非常重要的对象,可以用来判断是否是同一用户,还可以用来记录客户的连接信息等。HTTP协议是一种无状态的协议(即不保存连接状态的协议),每次用户请求在接收到服务器的响应后,连接就关闭了,服务器端与客户端的连接就被断开。因此,当用户的浏览器没关闭,这个时候又发起请求,那么网站就应该识别出该用户的情况。这种情况下,session对象就起到了关键作用。session相关概念见表4.3,常用方法见表4.4。

表4.3 session相关概念

表4.4 session对象常用方法

4.3.1 获取session ID

获取session对象ID可以判断会话是否是同一会话,用户可以通过会话中的信息来进行相关的操作。

【例4.8】获取session ID值

【程序结构】创建两个Web目录并部署应用,页面之间通过超链接联系起来。

假设有3个页面:ex4_2.jsp, ex4_3.jsp, ex4_4.jsp。ex4_2.jsp和ex4_3.jsp部署在同一应用下,ex4_4.jsp在另外一个应用中。ex4_2.jsp通过表单提交到ex4_3.jsp, ex4_2.jsp通过超链接指向ex4_4.jsp。ex4_3.jsp通过超链接指向ex4_2.jsp, ex4_3.jsp也通过超链接指向ex4_4.jsp。ex4_4.jsp通过表单提交到ex4_2.jsp。它们之间的关系如图4.12所示。

图4.12 页面之间的关系图

ex4_2.jsp发送请求和超链接到ex4_3.jsp和ex4_4.jsp,其源代码如下:

      -----------------ex4_2.jsp----------------
      01   <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
      02   <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
      03   <html>
      04    <head>
      05      <title>My JSP 'ex4_2.jsp' starting page</title>
      06       <meta http-equiv="pragma" content="no-cache">
      07       <meta http-equiv="cache-control" content="no-cache">
      08    </head>
      09    <body>
      10    <%
      11          String sessionID = session.getId();
      12          session.setAttribute("name", "John");            //存参数name
      13          String author = (String)session.getAttribute("author"); //强制转为
  String类型
      14          long time = session.getCreationTime();
      15          Date date = new Date(time);
      16     %>
      17     <center>
      18          <p>您访问的是ex4_2.jsp页面</br>
      19           <%=author %>,您的session对象ID为:</br>
      20             <%=sessionID%></br>
      21            session对象创建时间:<%=date %>
      22             </br>
      23           </p>
      24           <form action="ex4_4.jsp" method="post">
      25              <input type="submit" value="转向ex4_3.jsp"/>
      26           </form>
      27          <a href="../ch04/ex4_4.jsp">欢迎到ex4_4.jsp页面</a>
      28     </center>
      29    </body>
      30   </html>

上述代码中,第10~15行获取session中author参数值,并设置当前日期,第19~20行显示获取的参数值,页面效果如图4.13所示。

图4.13 ex4_2.jsp运行结果

从图4.13中可以看出,页面输出了session对象的ID值和创建的时间,但是没有获得从页面ex4_4.jsp传来的参数值author。

ex4_4.jsp超链接到ex4_4.jsp和ex4_4.jsp,其源代码如下:

      -----------------ex4_3.jsp----------------
      01   <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
      02   <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
      03   <html>
      04    <head>
      05      <title>My JSP 'ex4_3.jsp' starting page</title>
      06       <meta http-equiv="pragma" content="no-cache">
      07       <meta http-equiv="cache-control" content="no-cache">
      08    </head>
      09    <body>
      10    <%
      11          String sessionID = session.getId();
      12          String name = (String)session.getAttribute("name"); //强制转为
  String类型
      13          long time = session.getCreationTime();
      14          Date date = new Date(time);
      15     %>
      16     <center>
      17          <p>您访问的是ex4_3.jsp页面</br>
      18            <%=name %>,您的session对象ID为:</br>
      19             <%=sessionID%></br>
      20            session对象创建时间:<%=date %>
      21             </br>
      22           </p>
      23          <a href="ex4_2.jsp"><%=name %>,欢迎到ex4_2.jsp页面</a></br>
      24          <a href="../ch04/ex4_4.jsp"><%=name %>,欢迎到ex4_4.jsp页面</a>
      25     </center>
      26    </body>
      27   </html>

运行结果如图4.14所示。从图中可以看出,页面ex4_3.jsp获得的session对象ID和创建时间与ex4_2.jsp中的session对象ID和创建时间是一样的,且获得到了参数name的值。

图4.14 ex4_4.jsp运行结果

ex4_4.jsp发送请求和超链接到ex4_2.jsp,其源代码如下:

      -----------------ex4_4.jsp----------------
      01   <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
      02   <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
      03   <html>
      04    <head>
      05      <title>My JSP 'ex4_4.jsp' starting page</title>
      06       <meta http-equiv="pragma" content="no-cache">
      07       <meta http-equiv="cache-control" content="no-cache">
      08    </head>
      09    <body>
      10    <%
      11          String sessionID = session.getId();
      12          String name = (String)session.getAttribute("name"); //强制转为
  String类型
      13          session.setAttribute("author", "Smith");          //存参数author
      14          long time = session.getCreationTime();
      15          Date date = new Date(time);
      16     %>
      17     <center>
      18          <p>您访问的是ex4_4.jsp页面</br>
      19            <%=name %>,您的session对象ID为:</br>
      20             <%=sessionID%></br>
      21            session对象创建时间:<%=date %>
      22             </br>
      23           </p>
      24           <form action="../ch04/ex4_2.jsp" method="post">
      25              <input type="submit" value="转向ex4_2.jsp"/>
      26           </form>
      27     </center>
      28    </body>
      29   </html>

上述代码中,第11~15行获取session中的用户名参数,第18~21行显示参数值,页面效果如图4.15所示。

图4.15 ex4_4.jsp运行结果

从图4.15中可以看出,页面输出了session对象的ID值和创建时间,但是它和页面ex4_2.jsp、ex4_3.jsp页面的session对象的ID值不同,并且页面没有获得从ex4_2.jsp传来的参数值name。

从以上的结果可以看出:一个Web应用的session对象的ID值是唯一的,并且两个应用之间的参数用session对象是获取不到值的。

提示

读者务必要理解session对象的生命周期。

4.3.2 登录用户信息的保存

【例4.8】登录用户信息的保存

【程序结构】login.jsp是用户登录界面,validate.jsp页面是验证用户合法性界面,class.jsp页面是登录成功显示班级管理界面,logout.jsp是退出登录界面。它们之间的关系如图4.16所示。

图4.16 例4.8页面之间的关系

login.jsp登录页面,其源代码如下:

      -----------------login.jsp----------------
      01   <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
      02   <%
      03   String path = request.getContextPath();
      04   String basePath =
      05
  request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+
  path+"/";
      06   %>
      07   <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
      08   <html>
      09    <head>
      10      <base href="<%=basePath%>">
      11      <title>用户登录</title>
      12       <meta http-equiv="pragma" content="no-cache">
      13       <meta http-equiv="cache-control" content="no-cache">
      14       <meta http-equiv="expires" content="0">
      15       <meta http-equiv="keywords" content="keyword1, keyword2, keyword3">
      16       <meta http-equiv="description" content="This is my page">
      17    </head>
      18
      19    <body>
      20        <center>
      21             <font size="8">用户登录</font>
      22              <hr/>
      23              <form action="validate.jsp" method="post">
      24                  用户名称:<input type="text" name="username"/>
      25              <br/>
      26                  用户密码:<input type="password" name="password"/>
      27              <br/>
      28             <input type="submit" value="登录"/>
      29              </form>
      30        </center>
      31
      32    </body>
      33   </html>

上述代码中,第23~29行用form表单提交登录信息。

validate.jsp是验证页面,其源代码如下:

    -----------------validate.jsp----------------
    01   <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    02   <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    03   <html>
    04    <head>
    05      <title>success.jsp</title>
    06       <meta http-equiv="pragma" content="no-cache">
    07       <meta http-equiv="cache-control" content="no-cache">
    08       <meta http-equiv="expires" content="0">
    09       <meta http-equiv="keywords" content="keyword1, keyword2, keyword3">
    10       <meta http-equiv="description" content="This is my page">
    11    </head>
    12     <%!
    13        //声明一个用户集合,模拟从数据库中取出用户集
    14         Map<String, String> map =new HashMap<String, String>();
    15        //声明验证的标识
    16         boolean flag = false;
    17     %>
    18       <%
    19         //向集合添加数据
    20          map.put("John", "123456");
    21          map.put("Smith", "222222");
    22          map.put("Bob", "333333");
    23          map.put("Bruth", "666666");
    24       %>
    25       <%!
    26         //声明验证方法
    27          boolean validate(String username, String password){
    28              String passwd = map.get(username);
    29              if(passwd! =null&&passwd.equals(password)){
    30                 return true;
    31              }else{
    32               return false;
    33              }
    34          }
    35        %>
    36        <%
    37          //获得页面提交的用户名跟密码
    38           String username = request.getParameter("username");
    39           String password = request.getParameter("password");
    40
  if(username==null||username==""||password==null||password==""){
    41               response.sendRedirect("login.jsp");
    42           }
    43           flag = validate(username, password);
    44           if(flag){
    45              //保存在session对象中
    46               session.setAttribute("username", username);
    47               session.setAttribute("password", password);
    48               response.sendRedirect("class.jsp");
    49           }
    50         %>
    51       <body>
    52          <center>
    53             <font size="6">用户登录</font>
    54          </center>
    55          <br/>
    56          <center>
    57              <%if(! flag){ %>
    58                <a href="login.jsp">重新登录系统</a>
    59              <%} %>
    60          </center>
    61    </body>
    62   </html>

上述代码中,第18~24行设置用户集合;代码第26~35行声明验证用户合法性方法;第38~49行获取参数值,并判断其合法性,合法的保存在session中,否则跳转到login.jsp中。

class.jsp是班级管理页面,其源代码如下:

      -----------------class.jsp----------------
      01   <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
      02   <%
      03      String name = (String)session.getAttribute("username");
      04      if(name==null){
      05          response.sendRedirect("login.jsp");
      06      }
      07   %>
      08
      09   <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
      10   <html>
      11    <head>
      12      <title>My JSP 'score.jsp' starting page</title>
      13       <meta http-equiv="pragma" content="no-cache">
      14       <meta http-equiv="cache-control" content="no-cache">
      15       <meta http-equiv="expires" content="0">
      16       <meta http-equiv="keywords" content="keyword1, keyword2, keyword3">
      17       <meta http-equiv="description" content="This is my page">
      18    </head>
      19
      20    <body>
      21         <center>
      22            <font size="5">班级管理</font>
      23         <hr/>
      24        <h3>学生:<%=name %></h3>
      25         <table>
      26             <tr>
      27                <td>
      28                  <a href="addClass.jsp">班级录入</a>
      29                </td>
      30                <td>
      31                  <a href="modifyClass.jsp">班级修改</a>
      32                </td>
      33                <td>
      34                  <a href="queryClass.jsp">班级查询</a>
      35                </td>
      36                <td>
      37                  <a href="delClass.jsp">班级删除</a>
      38                </td>
      39             </tr>
      40         </table>
      41        <a href="logout.jsp">退出登录</a>
      42         </center>
      43    </body>
      44   </html>

上述代码中,第28~37行列出班级的各项方法。logout.jsp是退出页面,其源代码如下:-----------------logout.jsp----------------

    01   <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    02   <%
    03     String username = (String)session.getAttribute("username");
    04     session.removeAttribute("John");
    05     session.invalidate();
    06     response.sendRedirect("login.jsp");
    07   %>
    08
    09   <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    10   <html>
    11    <head>
    12      <title>My JSP 'logout.jsp' starting page</title>
    13    </head>
    14    <body>
    15    </body>
    16   </html>

【代码解析】

login.jsp页面中第23行代码form表单用post方式提交,action指向success.jsp页面。Validate.jsp页面中第12~17行代码是声明map集合和成功标识flag,第18~24行向map中添加数据,第25~34行是验证的方法,第36~50行是获得页面传递的参数以及验证学生是否存在,如果存在则存放在session中并重定向到class.jsp。第57~59行验证失败则显示重新登录。logout.jsp页面第2~6行获得session中的name参数值并移除该学生,session失效。

运行结果如图4.17所示。

图4.17 例4.8运行结果

提示

该例子用户退出,只是用简单的session.invalidate方法,在开发中经常是结合struts框架一起使用。