任务十 实现后台页面的身份检查
学习目标
了解自定义标签解析步骤。
了解tld文件的基本结构。
掌握web.xml中对标签的申明。
掌握taglib指令的用法。
理解自定义标签与网页之间的交互方式。
会设计简单的用于显示数据库数据的标签。
会设计检查登录状态的标签。
任务描述
绿吧企业门户网站的后台,实现了产品、新闻和留言的管理操作,只有特定权限的用户才能访问和操作,这种权限的限制是靠用户登录模块来实现的。如图1-10-1所示,所有后台的管理页面在进入之前,都应该判断当前访问页面的用户是不是经过了登录页面验证的合法用户。
图1-10-1 后台管理界面截图
根据前面学习的知识,为每个页面添加一个用户身份的判断语句并不困难。例如,可以在每一个后台页面的开始部分添加如下代码。
代码1-10-1 身份验证代码
这段代码实现的功能就是,判断当前会话对象中有没有存储登录用户的参数login,如果没有,就直接从这个页面跳转到登录页面,阻止了非法用户对当前页面的访问。
后台一共有7个页面,每一个页面都要重复写这段脚本,能不能使用更友好的界面方式来实现登录的判断呢?本次任务要求使用自定义标签技术实现页面进入前的身份判断。任务分析与相关知识
1.自定义标签概述
JSP页面除了支持HTML标签之外,还支持用户自定义的标签。例如<p>…</p>是HTML标签,而<mytags:hello>…</mytags:hello>就是自定义的标签。当然浏览器是不能识别自定义标签的,除非Web服务器按照自定义标签的解析路径,对该标签做了解析和转换,才能变成客户端浏览器能够识别的内容。所以作为自定义标签的设计者,一定要遵循服务器对标签的解析标准,才能设计出“能被读懂”的标签。
自定义标签从外观上看,具有显著的特点,如下:
<前缀:后缀/>或者<前缀:后缀>体内容</前缀:后缀>
也就是说,所有自定义标签名不像HTML标签是单独一个单词,而是两个部分构成,一个代表前缀,一个代表后缀,它们在标签解析过程中有着不同的作用。
例如,最简单的自定义标签结构如下:
<mytags:hello/>
带有属性、体内容的自定义标签结构如下:
<mytags:strongcolor="red"size="20">这是内容</mytags:strong>
自定义标签也有和普通标签一样的特点:都是<>括起来,有开始、有结束。
2.自定义标签的解析
当在JSP页面使用了自定义的标签,Web服务器是如何解析它们的呢?例如,如果在页面中使用了<mytags:hello/>,到底这个标签展示什么内容给用户呢?这就是标签的解析问题。
自定义标签的解析需要如下3个要素的参与:
1)标签解析类。这个类最终实现标签要完成的显示任务。既然叫它标签解析类,它必然有自己的身份象征,也就是这个类一定要继承一个父类,来明确自己的责任。例如,如果<mytags:hello/>的任务是在浏览器上显示“helloworld!”,那么显示“helloworld!”的工作任务必然是一个解析类完成的,假设这个类叫做HelloTag,那么这个类必须继承一个标记解析的框架类——TagSupport,该框架类告诉我们应该在什么地方编写代码,实现最终的显示任务。
演示一 定义一个简单的标签解析类HelloTag,实现在浏览器上显示“helloworld!”。
在Hello项目中添加一个新的类文件HelloTag.java,将该类放入tags包中,在HelloTag.java源文件中输入如下代码。
代码1-10-2 HelloTag.java
doStartTag和doEndTag就是来自父类的方法,我们不用深究,只要知道当服务器解析标签的时候,会先执行doStartTag方法里面的内容,再执行doEndTag里面的内容。
doStartTag方法需要一个返回值用来决定是否处理标签的主体内容,如果返回SKIP_BODY,就表示不处理标签的主体;如果返回EVAL_BODY,就表示要处理标签的主体。
doEndTag方法需要一个返回值用来决定是否处理自定义标签之后的内容,如果返回SKIP_PAGE,就表示不处理自定义标签之后的内容;如果返回EVAL_PAGE,就表示要处理。
代码1-10-2的第7行非常重要,pageContext.对象是标签解析类中最重要的方法。之所以这样说,是因为自定义标签是在JSP页面中使用的,我们都知道JSP页面中有一些默认对象可以使用,如request、response、out、session,这些对象可以实现与用户之间的交互。自定义标签作为JSP的一部分,也应该可以使用这些对象,否则自定义标签就无法实现与用户交互了。而pageContext.对象是一个桥梁,借助它,可以得到JSP页面中的所有默认对象。例如,如果需要在JSP页面输出HTML代码,就可以使用pageContext.getOut()获取JSP的默认对象out,再使用out的println方法输出任何需要输出的内容。
2)标记库描述文件——tld文件。tld文件如同前面的web.xml一样,是具有XML特色的标记文件。它的主要功能是根据自定义标签的后缀选择对应的标签解析类,也就是说,根据后缀指定一个标签解析类来负责这个标签的解析。
演示二 定义一个标记库描述文件。
在Hello项目根目录下的WEB-INF下添加一个tld文件mytags.tld。
代码1-10-3 mytags.tld
第1行是XML文件的申明,第2行是标记的申明,<taglib>是根节点,第10~15行是对一个标记的完整配置信息,其中name匹配自定义标记的后缀,tagclass指定解析类,相当于在自定义标记的后缀和解析类之间建立联系。上面的演示确定了后缀是“hello world!”的某个自定义标签由tags包下的HelloTag类来解析执行。
bodycontent指定这个标签是否有主体内容,如果没有就写empty,如果有,可以写JSP。
3)taglib指令与web.xml文件。自定义标签的JSP文件如何知道到在哪一个tld文件中寻找解析的线索呢?JSP文件与tld文件之间关联需要借助JSP的taglib指令和网站的配置文件web.xml文件。
例如,定义了一个JSP网页test_hellotag.jsp,里面包含一个自定义标签<mytags:hello>,tld文件和解析类在演示一、二中已经完成,那么为了让JSP找到指定的tld文件,从而最终找到解析类的位置,必须要添加一个taglib指令。
演示三 为test_hellotag.jsp文件添加taglib指令。
在Hello项目中添加一个新的JSP文件test_hellotag.jsp,该文件代码如下所示。
代码1-10-4 test_hellotag.jsp
第2行taglib指令中的prefix代表前缀,uri与代码1-10-5中的web.xml文件中的taglib-uri标签内容相互匹配,合在一起的含义是,JSP文件中的前缀是mytags的自定义标签,其解析信息在/WEB-INF/mytags.tld文件中描述。
打开Hello项目中的web.xml文件,在Servlet配置的前面添加如下标签。
代码1-10-5 web.xml部分标记
运行Hello网站,测试test_hellotag.jsp,效果如图1-10-2所示。
综上所述,自定义标签的解析过程如图1-10-3所示。
图1-10-2 test_hellotag.jsp运行效果
图1-10-3 <mytags:hello/>解析过程
3.自定义标签的其他用法
自定义标签还有很多扩展的用法,例如,带属性的标签、带体内容的标签和嵌套的标签。
演示四 展示带属性和主体内容的标签如何解析。
1)在Hello项目中新建一个类StrongTag,放入包tags中,源代码如下所示。
代码1-10-6 StrongTag.java
2)打开WEB-INF下的mytags.tld,为它添加一个tag标签(注意新添加的tag标签与之前定义的tag标签是平行的关系)。
代码1-10-7 修改mytags.tld(添加一个tag标签)
3)在Hello项目中添加一个新的JSP文件:test_strongtag.jsp,该文件代码如下所示。
代码1-10-8 test_strongtag.jsp
4)检查Hello项目下的web.xml文件,该文件应该包含如图1-10-4所示的taglib标签。
图1-10-4 web.xml中的taglib标签截图
运行网站,测试test_strongtag.jsp,效果如图1-10-5所示:
图1-10-5 test_strongtag.jsp运行效果
演示五 定义一个用来显示留言的自定义标签,减轻JSP的代码压力。
1)在任务八代码1-8-6修改的greenbardb.sql文件的结尾,添加如下代码。
代码1-10-9 greenbardb.sql增加的SQL语句
在MySQL数据库管理工具中重新执行greanbardb.sql文件,在原有数据表的基础上创建留言表words。
2)在项目GreenBar的models包下添加一个类文件WordBean.java,代码如下所示。
代码1-10-10 WordBean.java
3)在项目GreenBar的models包下添加一个类文件Words.java,代码如下所示。
代码1-10-11 Words.java
注意 代码中用到的DB类在任务八(代码1-8-3)中已经创建,这里不再提供代码。
4)在项目GreenBar下添加一个类文件WordTag.java,放入包tags中,代码如下所示。
代码1-10-12 WordTag.java
5)在项目GreenBar下WEB-INF下添加一个tld文件mytags.tld,代码如下所示。
代码1-10-13 mytags.tld
6)在GreenBar项目原来的web.xml中添加taglib标签,内容如图1-10-4所示。
7)在GreenBar项目中添加一个新的JSP文件words.jsp,代码如下所示。
代码1-10-14 words.jsp
运行GreenBar网站,测试words.jsp,效果如图1-10-6所示。
图1-10-6 words.jsp运行效果
任务实施
1.任务单
本次任务的任务清单见表1-10-1。
表1-10-1 任务十的任务清单
2.实施步骤
步骤一 确认数据库GreenBar中已经存在admins表(任务四的代码1-4-3创建了该表)。
步骤二 GreenBar项目根目录下添加一个mvclogin.jsp文件,如果任务八(任务八的代码1-8-1创建了该文件)已经完成此文件的创建,可以省略此步骤。
步骤三 检查GreenBar项目下是否有DB.java(任务八的代码1-8-3创建了该文件)、MemberBean.java(任务八的代码1-8-2创建了该文件)、Members.java(任务八的代码1-8-4创建了该文件)。
步骤四 修改GreenBar项目下原有的Servlet文件LoginController(任务八的代码1-8-5创建了该文件),修改后的代码如下所示。
代码1-10-15 修改后的LoginController.java
步骤五 在GreenBar项目下tags包下添加一个类文件CheckLoginTag.java,代码如下所示。
代码1-10-16 CheckLoginTag.java
步骤六 打开GreenBar下的WEB-INF下的mytags.tld,为它添加一个tag标签(注意新添加的tag标签与之前定义的tag标签是平行的关系)。
代码1-10-17 修改mytags.tld(添加一个tag标签)
步骤七 在GreenBar项目原来的web.xml中添加taglib标签,内容如图1-10-4所示(如果已经添加可以省略此步),另外检查之前创建的LoginController.java这个Servlet的路径映射是否是login。
到此,用来作身份验证的自定义标签就算是定义完成了,剩下就是如何使用自定义标签的问题。
步骤八 使用自定义标签:在需要作登录判断的页面最上面,添加如下两行代码:
现以后台管理的新闻发布页面为例,展示这个标签的用法。因为只有JSP文件才能使用自定义标签,所以在原来GreenBar项目下创建的bk_news_upload.html先要转换成JSP文件。具体转换方法如下:
1)添加一个新的JSP文件bk_news_upload.jsp,然后保留bk_news_upload.jsp文件中的第一行,并把编码改为UTF-8,其他行全部删除掉。
2)在bk_news_upload.jsp文件第2行处添加如下两行代码:
3)将bk_news_upload.html全部代码复制粘贴到bk_news_upload.jsp的第4行之后。
4)测试运行GreenBar项目,浏览bk_news_upload.jsp页面,发现页面会直接跳转到bk_login.html。登录之后再测试,就可以正常访问新闻发布页面了。
自我评价
思考与练习
一、简答题
1.自定义标签与HTML标准标签的区别是什么?
2.简述web.xml、tld文件和标签解析类在自定义标签实现过程中的作用。
二、填空题
1.TagSupport类中处理标签解析的两个核心方法是和。
2.tld文件中tag标签的子标签有、、和等。
三、操作题
模仿本次任务的演示五,使用自定义标签实现后台获取留言者的email列表,效果如图1-10-7所示。
图1-10-7 后台获取email列表效果图