Servlet的学习之Session(4)
在本篇中,我们来使用Session完成一个用户登录的案例,前提声明:这个案例主要用于学习Session技术,是属于比较简单的类型,以后会采用MVC模式来开发登录,那就会比较复杂。
现在大多数网站都提供登录功能,而我们之所以登录要使用到Session,在于当一个网站不同的页面里面都需要判断用户是否已经登录才能显示某些具有网站会员权限的功能,所以使用Session对象来保存用户登录标志最合适不过,同时,当用户注销登录时,也需要将Session中的用户标志移除,这样用户在继续访问网站或该网站其他页面时才能看到用户状态不再是已经登录状态。
另外注意,如果我们不用URL重写的话,请确保浏览器没有禁用Cookie;而如果我们不想去理会浏览器是否禁用Cookie,请对该web工程中涉及的超链接URL或转发URL进行URL重写(并在最开始的部分进行getSession()获取首次Session)。
现在开始进行使用Session进行用户登录的开发:
我们先要建立用户的JavaBean对象,在dao包中创建User对象,注意这里要采用“public”权限,这是因为在之后JSP页面中需要使用到User对象。
1 public class User { 2 private String userName; 3 private String password; 4 。。。//这里get和set方法及构造器方法均省略 5 }
接着我们需要建立数据库,我们还是在database包中建立UserDatabase类来模拟数据库(还是因为数据库没学T_T!),同时在数据库中模拟建立已经注册的用户:
1 public class UserDatabase { 2 private static Map<String,User> map = new HashMap<String, User>(); 3 4 static { 5 map.put("userId1", new User("aaa","123")); 6 map.put("userId2", new User("bbb","1234")); 7 map.put("userId3", new User("ccc","12345")); 8 } 9 10 public static Map<String,User> getAllUser() { 11 return map ; 12 } 13 14 }
现在我们可以创建用户登录的界面了,这里采用HTML(JSP还没学嘛,怎么这么多要学T_T):
1 用户登录 <br><br> 2 <form action="/LoginProject/servlet/LoginHandler" method="post"> 3 用户名: <input type="text" name="user"> <br/> 4 密码 : <input type="password" name="password"> <br/> 5 <input type="submit" value="提交"> 6 </form>
从表单提交的路径可以看出,我们所做的处理登录的Servlet名为LoginHandler,在这个Servlet中我们要对从表单提交的用户名和密码与数据库中进行验证,如果验证成功,则创建(或获取)Session,将这个Session中保存这个用户的标记,用于表示所有资源可以先对Session中这个标记进行判断用户是否登录,再进行对应功能的显示。最后登录成功的话我们就跳转到到某个页面:
1 //获取表单的用户名和密码 2 String username = request.getParameter("user"); 3 String password = request.getParameter("password"); 4 5 Map<String,User> map = UserDatabase.getAllUser(); 6 7 for(Map.Entry<String, User> entry : map.entrySet()) { 8 User u = entry.getValue(); 9 if(u.getUserName().equals(username) && u.getPassword().equals(password)){ 10 //用户名和密码均匹配,登录成功 11 request.getSession().setAttribute("user", u); 12 13 //登录成功后跳转到首页 14 response.sendRedirect("/LoginProject/index.jsp"); 15 16 return; 17 } 18 } 19 20 //如果用户名或密码匹配失败,则登录失败 21 response.setCharacterEncoding("UTF-8"); 22 response.setContentType("text/html;charset=utf-8"); 23 response.getWriter().print("登录失败"); 24
从上面代码中可以看到,如果我们登录成功的话,就跳转到index.jsp,在这个页面中我们需要简单使用JSP, 为了用户的体验效果,我们可以调用Session来将用户显示出来,同时加入“注销”超链接:
1 <body> 2 "您好 ,欢迎您: 3 <% 4 User user = (User) session.getAttribute("user"); 5 if(user!=null) 6 out.write(user.getUserName()); 7 %> 8 9 <a href="/LoginProject/servlet/LogoutHandler">注销</a> 10 <br> 11 </body>
在这段JSP中使用到了最开始我们对定义用户User的Javabean对象(这就是为什么要将User类进行public权限定义)。
注意:如果在这个页面中User出现了“User cannot be resolved to a type”的错误,那么就是JSP无法默认帮我们导入User所在的包,那么我们就必须在该JSP中手动导入:<%@ page import="fjdingsd.dao.User" %>,导入的位置在可以在<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>这个之后:
到此,如果我们输入正确的用户名和密码,则能正确登录,并在页面上看到显示的用户名,如果我们想退出登录状态,点击“注销”这个超链接,将会交给LogoutHandler这个Servlet处理。
在LogoutHandler这个Servlet中要处理的是将Session中保存用户的标识给剔除,这样其他页面在判断用户是否登录中就知道用户已经退出登录。同时我们可以在这个代码中再次(可以用作验证)判断Session的标识是否剔除,然后在服务器上显示用户下线。最后再回到开始的登录页面:
1 HttpSession session = request.getSession(false); 2 User user = (User)session.getAttribute("user"); 3 if(user != null) { 4 session.removeAttribute("user"); 5 } 6 7 if(session.getAttribute("user")==null) { 8 System.out.println("用户: "+user.getUserName()+" 已经下线!"); 9 } 10 response.sendRedirect("/LoginProject/login.html");
这就是整个简单的登录流程。
我们来看看效果,首先是登录页面:
正确登录进去,可以看到登录的用户,这个用户对象的获取是在JSP中从Session中获取的:
当我们点击注销后,看服务器的控制台,会看到确实已经将Session中用户的标识给清除了,Session中再也没有“user”这个属性:
Session中已经没有“user”这个属性了,也代表着用户已经注销登录,同时页面也重新回到了登录页面,等待下次用户的登录,等待着Session中重新为登录的用户定义新的“User”属性标识。