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框架一起使用。