完整版JSP页面的访问控制.docx
- 文档编号:11276112
- 上传时间:2023-02-26
- 格式:DOCX
- 页数:25
- 大小:2.04MB
完整版JSP页面的访问控制.docx
《完整版JSP页面的访问控制.docx》由会员分享,可在线阅读,更多相关《完整版JSP页面的访问控制.docx(25页珍藏版)》请在冰豆网上搜索。
完整版JSP页面的访问控制
JSP页面的访问控制
1.1 访问控制
1.1.1 如何实现访问控制
如图1.1和图1.2所示是系统进行访问控制的两种情形。
在图1.1中,用户通过登录页面登录网站,如果该用户是已注册用户,系统会保存该用户的登录信息,并让用户进入其欲访问的页面。
在图1.2中,用户直接访问网站的某个页面,系统会去查询是否保存有该用户的登录信息,如果有,则显示该页面的内容,如果没有,就转入登录页面,要求用户登录网站。
图1.1 访问控制流程
(1)
图1.2 访问控制流程
(2)
JSP为提供了一套会话跟踪机制,该机制可以维持每个用户的会话信息。
也就是说,使用会话跟踪,可以为不同的用户保存不同的数据。
1.1.2 什么是会话
就Web开发来说,一个会话就是用户通过浏览器与服务器之间进行的一次通话,它包含浏览器与服务器之间的多次请求、响应过程。
如图1.3所示描述了浏览器与服务器的一次会话过程。
当用户向服务器发出第一次请求时,服务器会为该用户创建唯一的会话,会话将一直延续到用户访问结束(浏览器关闭,本次会话结束)。
图1.3 一次会话过程
JSP提供了一个可以在多个请求之间持续有效的会话对象session,session对象允许用户存储和提取会话状态的信息。
接下来,就来学习JSP内置对象session。
1.1.3 JSP内置对象session
在JSP中,提供了一个内置对象session,session对象用来存储有关用户会话的所有信息。
session对象的常用方法如下:
ØvoidsetAttribute(Stringkey,Objectvalue):
以键/值的方式,将一个对象的值存放到session中去。
例如:
session.setAttribute("name","admin");
就是把字符串admin存放到session中去,它对应的键是name。
ØObjectgetAttribute(Stringkey):
根据键去获取session中存放的对象的值。
例如:
Stringname=(String)session.getAttribute("name");
就是通过名称为name的键获取session中存放的对象的值。
在JSP中,访问控制就是基于session对象来完成的,接下来,就使用JSP内置对象session为新闻发布系统增加访问控制。
1.1.4 为新闻发布系统增加访问控制
现在升级新闻发布系统,增加访问控制功能,要求系统提供用户登录页面,所有用户必须登录之后,才能访问新闻发布系统。
访问控制流程如图1.4所示。
图1.4 新闻发布系统的访问控制流程
根据新闻发布系统的访问控制流程,至少要完成如下几个步骤。
(1)在news数据库中创建表userinfo,负责存储用户名、密码。
(2)创建类(User.java),负责存储登录用户的信息,如用户名、密码。
(3)创建登录页面(login.html)。
(4)创建登录处理页面(login.jsp)。
(5)在新闻发布系统首页面中加入登录验证。
下面,就逐步完成这项升级任务。
首先,在news数据库中创建表userinfo,表结构见表1.1。
表1.1 数据表userinfo
字段名称
字段说明
数据类型
大小
loginName
用户名称
varchar
50
password
密码
varchar
50
接下来,创建类User.java,用来存储已登录用户的用户名和密码,代码实现如示例 1所示。
示 例 1
packages2.java.web.sg1.entity;
publicclassUser{
privateStringname;//用户名
privateStringpassword;//密码
/**
*构造函数
*
*@paramname用户名
*@parampassword密码
*/
publicUser(Stringname,Stringpassword){
this.name=name;
this.password=password;
}
/**
*返回用户名
*/
publicStringgetName(){
returnname;
}
/**
*返回密码
*/
publicStringgetPassword(){
returnpassword;
}
/**
*设定用户名
*@paramname
*/
publicvoidsetName(Stringname){
this.name=name;
}
/**
*设定密码
*@parampassword
*/
publicvoidsetPassword(Stringpassword){
this.password=password;
}
}
登录页面login.html非常容易编写,代码实现如示例2所示。
示 例 2
functionloginSubmit(){
if(form1.loginName.value==null||form1.loginName.value==""){
alert("请填写用户名!
");
returnfalse;
}
if(form1.password.value==null||form1.password.value==""){
alert("请填写密码!
");
returnfalse;
}
returntrue;
}
用户名:
密 码:
要在登录处理页面中进行一系列的逻辑处理:
首先查询数据库判断该用户是否已注册,接着在session中保存已登录用户的信息,代码实现如示例3所示。
示 例 3
<%@pagelanguage="java"contentType="text/html;charset=GBK"%>
<%@pageimport="java.sql.*"%>
<%@pageimport="s2.java.web.sg1.ConnectionManager"%>
<%@pageimport="s2.java.web.sg1.entity.User"%>
<%
request.setCharacterEncoding("GBK");
Stringpass=request.getParameter("password");
Stringname=request.getParameter("loginName");
Connectioncon=null;
PreparedStatementpStatement=null;
try{
con=ConnectionManager.getConnection();
Stringsql="select*fromuserinfowhereloginname=?
andpassword=?
";
pStatement=con.prepareStatement(sql);
pStatement.setString(1,name);
pStatement.setString(2,pass);
ResultSetrs=pStatement.executeQuery();
if(rs.next()){//如果是已注册用户
//把用户名、密码封装在User对象中
UserloginedUser=newUser(name,pass);
//在session中存放用户登录信息
session.setAttribute("LOGINED_USER",loginedUser);
//进入新闻发布系统的首页面
response.sendRedirect("index.jsp");
}else{
response.sendRedirect("login.html");
}
}catch(Exceptione){
out.println("发生错误!
错误原因:
"+e.getMessage());
}finally{
ConnectionManager.closeStatement(pStatement);
ConnectionManager.closeConnection(con);
}
%>
在新闻发布系统首页面中加入登录验证。
此时要完成的任务是:
从session中提取用户的信息,如果用户信息存在,显示首页内容;如果用户信息不存在,跳转到登录页面。
已经完成了图1.1所示的访问控制流程。
但是如果此时用户直接在浏览器地址栏中输入新闻发布系统首页面的地址,还是能够不受登录限制而访问成功的。
接下来要完成的就是图1.2所示的访问控制流程。
具体代码实现如示例4所示。
示 例 4
<%@pagelanguage="java"contentType="text/html;charset=GBK"%>
<%@pageimport="s2.java.web.sg1.entity.User"%>
<%
//如果session中不存在该用户的登录信息,转入登录页面
Useruser=(User)session.getAttribute("LOGINED_USER");
if(user==null){
response.sendRedirect("login.html");
}
%>
至此为止,新闻发布系统的访问控制已经基本实现了。
还需要验证一下访问控制的效果,具体步骤可分为如下几步。
(1)直接在浏览器地址栏中输入URL,访问系统首页面。
(2)通过登录页面进入系统首页面。
(3)重新开启一个浏览器窗口,直接访问系统首页面。
按照上述步骤运行一下,看看每个步骤会发生什么样的结果,并思考一下为什么会产生这样的结果。
现在,来分析一下。
如果直接在浏览器地址栏中输入URL,访问系统首页面,那么系统会跳入登录页面,提示用户进行登录。
这个原因很简单,因为在系统首页面中加入了登录验证。
如果通过登录页面进入系统首页面,那么只要是已注册用户,都可以正常进入。
这个可以通过登录处理页面的代码(示例3)得到解释。
如果重新开启一个浏览器窗口,直接访问系统首页面,那么不管你在其他窗口中是否登录,你进入的肯定是登录页面。
这是因为:
每个session对象都与浏览器一一对应,也就是说,重新开启一个浏览器窗口,相当于重新创建一个session对象,在其他浏览器窗口保存的登录信息与新的浏览器窗口完全无关,所以系统会判定尚未登录,必定跳转进入登录页面。
1.1.5 include指令
在新闻发布系统中,除了首页面,还有许多二级页面,同样要求只有登录用户才能够访问。
那么现在就有一个问题需要解决,看下面的问题:
如果要为多个页面添加登录验证,有没有办法避免重复代码的出现?
JSP为提供了文件引用指令include。
可以将一些共性的内容写入一个单独的文件中,然后通过include指令引用该文件,从而缓解代码的冗余问题,并且修改起来也更加方便,即对这些共性内容只需要修改那个独立的文件即可。
首先,需要创建登录验证文件checklogin.jsp,代码实现如示例5所示。
示 例 5
<%@pageimport="s2.java.web.sg1.entity.User"%>
<%
Useruser=(User)session.getAttribute("LOGINED_USER");
if(user==null){
response.sendRedirect("login.html");
}
%>
示例 5 的代码与示例4中进行登录验证的那部分代码一模一样。
有了这个独立的文件,只需在系统首页面和其他二级页面中引用该文件就可以了,代码实现如示例 6所示。
示 例 6
<%@pagelanguage="java"contentType="text/html;charset=GBK"%>
<%@pageimport="s2.java.web.sg1.entity.User"%>
<%@includefile="checklogin.jsp"%>
1.2 已访问人数统计
1.2.1 为新闻发布系统增加已访问人数统计功能
升级新闻发布系统,增加已访问人数统计功能,具体要求如下。
左导航页面中增加一个超链接“已访问人数统计”,单击该超链接后,进入已访问人数统计页面,该页面显示已访问人数,以及访问者的登录名称,如图1.5所示。
图1.5 已访问人数统计页面
为了实现这一功能,需要完成以下工作。
(1)创建登录页面(login2.html)。
(2)创建登录处理页面(login2.jsp),把已登录用户的信息保存在一个全局范围内。
(3)在左导航页面(left.jsp)中加入超链接,链接至已访问人数统计页面。
(4)创建已访问人数统计页面(showAllLoginedUsers.jsp),把已登录用户的信息从全局范围内取出来。
下面,就逐步完成这项升级任务。
首先,创建登录页面login2.html,这个登录页面与示例2中的login.html非常相似,只需把form表单的提交地点改为login2.jsp就可以了。
接着,进入一个关键的环节,创建登录处理页面login2.jsp。
代码实现如示例7所示。
示 例 7
<%@pagelanguage="java"contentType="text/html;charset=GBK"%>
<%@pageimport="java.sql.*"%>
<%@pageimport="java.util.*"%>
<%@pageimport="s2.java.web.sg1.ConnectionManager"%>
<%@pageimport="s2.java.web.sg1.entity.User"%>
<%
request.setCharacterEncoding("GBK");
Stringpass=request.getParameter("password");
Stringname=request.getParameter("loginName");
Connectioncon=null;
PreparedStatementpStatement=null;
try{
con=ConnectionManager.getConnection();
Stringsql="select*fromuserinfowhereloginname=?
andpassword=?
";
pStatement=con.prepareStatement(sql);
pStatement.setString(1,name);
pStatement.setString(2,pass);
ResultSetrs=pStatement.executeQuery();
if(rs.next()){//如果是已注册用户
Userlogineduser=newUser(name,pass);
session.setAttribute("LOGINED_USER",logineduser);
ListloginedUsers=newArrayList();//访问者列表
//从全局范围内取出原有的访问者列表
if(application.getAttribute("LOGINED_USER")!
=null){
loginedUsers=(List)application.getAttribute("LOGINED_USER");
}
//把新登录用户的信息存入访问者列表中
loginedUsers.add(logineduser);
//在全局范围内存入访问者列表
application.setAttribute("LOGINED_USER",loginedUsers);
response.sendRedirect("index.jsp");
}else{
response.sendRedirect("login2.html");
}
}catch(Exceptione){
out.println("发生错误!
错误原因:
"+e.getMessage());
}finally{
ConnectionManager.closeStatement(pStatement);
ConnectionManager.closeConnection(con);
}
%>
示例7同样实现了访问控制功能,除此之外,示例7的粗体部分则是为了实现已访问人数统计的功能,这段代码的主要用途是把已登录用户的信息存入一个集合中,该集合在全局范围内有效。
其中使用到了一个JSP内置对象application,它类似于系统的全局变量,用于实现用户之间的数据共享。
稍后将详细介绍这个内置对象,此处了解其基本用途就可以了。
接下来的工作较为简单,就是在左导航页面(left.jsp)中加入超链接,链接至已访问人数统计页面,代码实现如示例8所示。
示 例 8
<%@pagelanguage="java"contentType="text/html;charset=GBK"%>