【问题引入】
大家可能经常碰到这样的问题,比如我们在使用百度文库时,当想下载某文档时,系统会自动转入登录页面,提示用户登录后才能下载。当然,如果是已登录用户,就不会面临这样的问题了。那么,网络应用系统是如何判断用户是否已经登录过的呢?也就是说,系统如何实现对网站的访问控制呢?
【实现思路】
通常情况下,用户登录后的整个访问过程都会用到用户登录信息,JSP的session对象能在一段时间内保存用户的登录信息,所以通常会在用户登录之后把用户信息保存在session中。而在其他页面中访问session中的用户信息,从而实现访问控制。
【知识链接】
1 访问控制流程
系统进行访问控制有以下两种情形:
HTTP协议是一种无状态的协议,也就是说,它不能有效地记录整个访问过程中的一些状态。JSP提供了一套会话跟踪机制,该机制可以维持每个用户的会话信息,可以为不同的用户保存不同的数据。对Web开发来说,一个会话就是用户通过浏览器与服务器之间进行的一次通话,它包含浏览器与服务器之间的多次请求、响应过程。当浏览器关闭时,相应的用户会话结束。
JSP中,session内置对象用来存储有关用户会话的所有信息,一个用户对应一个session,并且随着用户的离开session中的信息也会消失。访问控制就是使用session对象完成的。
2 使用session对象保存信息
session对象的setAttribute()方法用来保存用户信息,其语法格式为:
session.setAttribute(String key,Objectvalue);
key表示键,value表示值,value必须是一个Object类型,该方法表示以键/值的方式将一个对象的值存放到session中去。
3 使用session对象获取信息
session对象的getAttribute()方法用来获取session对象中存放的对象的值,其语法格式为:
(要强制转换的类型)session.getAttribute(String key);
key表示键,该方法表示以键的方式获取session对象中存放的对象的值,此方法的返回值是一个Object,必须要进行强制类型转换。
4 从session中移除指定的对象
对于存储在session会话中的对象,如果想将其从session会话中移除,可以使用session对象的removeAttribute()方法,其格式如下:
session.removeAttribute(Stringkey);
key表示键,该方法表示以键的方式移除session对象中存放的对象,一般用在注销登录功能中。
【例2.8】依据访问控制流程完善例2.6中的用户登录代码,用户登录成功后保存用户信息(用户名和密码)。
实现如下:
(1)编写User类,该类在entity包下,用于存放用户名及密码。
清单2-18 entity.User.java
| package entity; public class User { private String name; private String password; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } |
(2)编写login.jsp页面,为登录页面。
清单2-19 login.jsp
| <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <title>用户登录</title> </head> <body> 请输入用户名和密码: <form action="dologin.jsp" method="post"> 用户名:<input type="text" name="uname"><br> 密 码:<input type="password" name="pwd"><br> <input type="submit" value="登录"><input type="reset" value="重置"> </form> </body> </html> |
(3)编写dologin.jsp页面,为登录处理页面,用来进行登录验证,依据访问控制流程,需要将成功登录的用户信息存放在session中,然后再转向欲访问的welcome.jsp页面。
清单2-20 dologin.jsp
| <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="entity.*"%> <html> <head> <title>登录处理</title> </head> <body> <%request.setCharacterEncoding("utf-8"); String name=request.getParameter("uname"); String pwd=request.getParameter("pwd"); User user=new User(); user.setName(name); //将用户名封装在user中 user.setPassword(pwd); //将密码封装在user中 if(name.equals("张三")&&pwd.equals("123")) { //把user对象存放到session中去,它对应的键为loginuser session.setAttribute("loginuser",user); response.sendRedirect("welcome.jsp"); } else response.sendRedirect("login.jsp"); %> </body> </html> |
【例2.9】依据访问控制流程完善例2.8,要求非登录的用户不能访问欲访问的welcome.jsp页面。
实现:仅需修改例2.8中的welcome.jsp,增加清单2-21中加粗的代码部分。
清单2-21 welcome.jsp
| <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="entity.*"%> <html> <head> <title>登录成功</title> </head> <body> <%User user=(User)session.getAttribute("loginuser"); //获取用户对象 if(user==null)response.sendRedirect("login.jsp"); //未登录的情况 %> 欢迎<%=user.getName() %>! </body> </html> |
清单2-21中的粗体部分即为判断session是否保存了用户登录信息。session只存储已登录的用户信息。至此,访问控制已实现。现在可通过以下几步来验证访问控制的效果:
(1)直接在浏览器地址栏中输入URL,访问welcome.jsp页面。
(2)通过登录页面进入welcome.jsp页面。
(3)重新开启一个浏览器窗口,直接访问welcome.jsp页面。