JSP自定义标签学习【轻松了解JSP自定义标签过程】
声明:本文由本人将多篇文章整合而成,非本人原创。
?
JSP处理逻辑:
JSP标签其实,是由服务端的Java类执行一些处理后,翻译成HTML,然后返回 给客户端,渲染展示出来。
附图:

?
JSP具体处理步骤如下:
?
1.在JSP中引入标签库:
?1
<% @ taglib prefix=”taglibprefix” uri=”tagliburi” %>
2.在JSP中使用标签库标签
3.Web容器根据第二个步骤中的prefix,获得第一个步骤中声明的taglib的uri属性值
4.Web容器根据uri属性在web.xml找到对应的元素
5.从元素中获得对应的元素的值
6.Web容器根据元素的值从WEB-INF/目录下找到对应的.tld文件
7.从.tld文件中找到与tagname对应的元素
8.凑元素中获得对应的元素的值
9.Web容器根据元素的值创建相应的tag handle class的实例
10. Web容器调用这个实例的doStartTag/doEndTag方法完成相应的处理
?
?
自定义标签的步骤如下
- 扩张TagSupport
- 写自定义Tag的tld文件
- web.xml中指定你的tld文件
- 在JSP页面使用自定义标签
?
??? ??? 说明:
??? ??? ??? ??? 一般不会去实现Tag接口,而是通过TagSupport类是实现了Tag的接口继承过来的字段,这些字段用做public int??? ????????? doStartTag(),public int doEndTag()返回值
??? ?? ??? ? ??Tag.EVAL_BODY_INCLUDE 包含主体内容
??? ?? ??? ? ??Tag.SKIP_BODY???? 不包含主体内容
??? ?? ??? ? ??Tag.EVAL_PAGE??? ? 包含后面的页面内容
??? ?? ??? ? ??Tag.SKIP_PAGE???? 不包含主体的内容????
?
实现一个简单实现代码:
java 代码
?
- package?com.mercyblitz;??
- import?java.io.IOException;??
- import?javax.servlet.jsp.JspException;??
- import?javax.servlet.jsp.JspWriter;??
- import?javax.servlet.jsp.tagext.TagSupport;??
- ??
- public?class?MyTags?extends?TagSupport?{??
- ????public?int?doStartTag()throws?JspException??
- ????{??
- ????????JspWriter?out=pageContext.getOut();??
- ????????try??
- ????????{??
- ????????????out.println("Hello,World");?//页面中显示的内容??
- ????????}catch(IOException?e)??
- ????????{??
- ????????????throw?new?JspException(e);??
- ????????}??
- ????????return?SKIP_BODY;?//不包含主体内容??
- ????}??
- }??
?
xml 代码
?
- <?xml?version="1.0"?encoding="UTF-8"?>??
- <!DOCTYPE?taglib?PUBLIC?"-//Sun?Microsystems,?Inc.//DTD?JSP?Tag?Library?1.2//EN"?"web-jsptaglibrary_1_2.dtd"?>??
- <taglib>??
- ??<tlibversion>tlibversion</tlibversion>??<!--?你自定义标签的版本数?-->??
- ??<jsp-version>1.2</jsp-version>??<!--?指定你的JSP版本,扩张标签是在JSP1.2之后兼容的?--?>??
- ??<shortname>shortname</shortname>?<!--?标签的简写?-->??
- ??<tag>??
- ????<name>tags</name>??<!--?标签名字?-->??
- ????<tagclass>com.mercyblitz.mytags</tagclass>??<!--?指定你的标签的类?-->??
- ??</tag>??
- </taglib>??
???????? 标签库元素<taglib>属性:表格如下
????????
<taglib>属性表格</taglib>
属性
描述
tlib-version
本标签库实现版本
jsp-version
标签库依赖的JSP版本
short-name
被JSP创作工具使用的一个短的默认名词
uri
指定这个标签库的uri信息
display-name
被工具使用的显示用的名字
small-icon
被工具使用的小图标
large-icon
被工具使用的大图标
description
本标签的描述
validator
TLD验证信息
listener
实践监听器规范
??? ??? tag标签相关属性:
tag标签相关属性表
属性
描述
name
tag标签唯一的名称
tag-class
tag标签的处理类
tei-class
tag标签的TagExtraInfo类
body-content
标签主体的内容
display-name
显示的名称
small-icon
被工具使用的小图标
large-icon
被工具使用的大图标
description
本标签的描述
variable
脚本变量的信息
attribute
标签属性的信息
???????????这些呢,是为以后高级内容说要提到的!
xml 代码
?
?- <?xml?version="1.0"?encoding="UTF-8"?>??
- <web-app?version="2.4"???
- ????xmlns="http://java.sun.com/xml/ns/j2ee"???
- ????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"???
- ????xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee???
- ????http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">??
- ????<welcome-file-list>??
- ???????<welcome-file>/WEB-INF/mytag.jsp</welcome-file>?<!--?设置欢迎页面?-->??
- ????</welcome-file-list>??
- ????<jsp-config>??
- ??????????<taglib>??
- ????????<taglib-uri>http://mercyblitz.blog.ccidnet.com/taglibs.tld</taglib-uri>?<!--?设置自定义标签的uri(不一定存在,但是一定要唯一),为页面的部署做好准备??
- ????????<taglib-location>/WEB-INF/taglibs.tld</taglib-location>??<!--定位你的tld文件的相对路径?-->??
- ??????</taglib>??
- ????</jsp-config>??
- </web-app>?
html 代码
?
?- <%@?page?language="java"?import="java.util.*"?pageEncoding="GBK"%>??
- <%@?taglib?uri="http://mercyblitz.blog.ccidnet.com/taglibs.tld"?prefix="out"?%>??
- <html>??
- ??<head>??
- ????<title>mytag.jsp</title>??
- ??</head>????
- ??<body>??
- ????<out:tags/>? <!-- 页面执行的结构,就是:? Hello,World -->
- ??</body>??
- </html>??
BodyTag接口
??? 接口BodyTag的实现类,它是负责操作主体内容(bodyContent).
定义方法:public void doInitBody();
??? public int doAtferBody();
提示,那些在doStartTag()方法之后被调用的方法依赖于doStartTag()方法返回值并且看在JSP页面上是否自定义Action元素,而不是怎样在TLD文件中去申明
??? 在TLD文件中, 若<body-content>empty</body-content>的话,doStartTag()方法只能返回SKIP_BODY
??? body-content有三个可选值:empty , JSP ,tagdependent
??? 若没有设置的话,那么doStartTag()可以返回SKIP_BODY, EVAL_BODY_INCLUDE, or EVAL_BODY_BUFFERED.
返回值的说明:
??? 若SKIP_BODY返回的情况下,body不会被evaluated并且doEndTag()被调用;
??? 若EVAL_BODY_INCLUDE 返回,并且自定义action元素不为空的时候,那么doInitBody(),setBodyContent()不会被调用,而body evaluated并且"通过"当前的out对象,还有当action元素为空的时候,只有doStartTag(),doEndTag();
???
??? 当EVAL_BODY_BUFFERED 返回,并且自定义的action元素不为空的时候,setBodyContent(),doInitBody()被调用,body被 evaluated,doAfterBody()被调用,直到大于0次迭代后,doEndTag()才被调用,还有当action元素为空的时候,只有doStartTag(),doEndTag();
主题内容
?? 1.自定义标记通常需要操控自己的主体内容,例如数据库查询需要将其主题内容解释为SQL
??? ???
??? 2.工作方法
??? servlet容器包含BodyContent对象栈,servlet容器在doStartTag()方法之后调用 PageContext.pushBody(),就是说把当前的主体内容推入栈中,其中out变量重定向到当前的主体内容实例主题内容,保留一个到 JspWriter对象的引用,即前一个输出,JspWriter将数据写入响应流中.这样就有效地创建了写入器栈
??? servlet容器是在调用标记的doAfterBody和doEndTag方法之间调用PageContent.popBody()方法的
注意请不要在doEndTag()后面去访问BodyContent,因为servlet容器在调用标记处理程序的doEndTag()方法为 止,servlet容器可能已经再次使用了该标记的主题内容,使用doEndTag方法访问自己主体内容的标记,可能会访问到其他标记的主体内容,或者可 能访问到空值,这样就导致了不确定的行为
BodyTagSupport类,实现BodyTag接口的类
??? public BodyContent getBodyContent();//返回主题内容
??? public JspWriter getPreviousOut();//返回前一个out对象
???
写个东西来说明以下:
打印出主体内容!
java 代码
?
- import?java.io.IOException;??
- ??
- import?javax.servlet.jsp.JspException;??
- import?javax.servlet.jsp.tagext.BodyTagSupport;??
- ??
- public?class?PrintBodyTag?extends?BodyTagSupport?{??
- ????public?int?doAfterTag()throws?JspException??
- ????{??
- ????????try??
- ????????{?????????
- ????????????this.getBodyContent().writeOut(getPreviousOut());//上面讲的理论!??
- ????????}catch(IOException?e)??
- ????????{??
- ????????????throw?new?JspException(e);??
- ????????}??
- ????????return?SKIP_BODY;??
- ????}??
- }??
部署tld文件
xml 代码
?
- ......??
- ??<tag>??
- ????<name>printBody</name>??
- ????<tag-class>PrintBodyTag</tag-class>??
- ??????
- ??</tag>??
- ??......??
页面加载:
html代码
?
- <%@?page?language="java"?import="java.util.*"?pageEncoding="ISO-8859-1"%>??
- <%@?taglib?uri="http://www.eimhe.com/taglibs/util.tld"?prefix="util"%>??
- <!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN">??
- <html>??
- ??<head>??
- ????<title>My?JSP?'tag.jsp'?starting?page</title>??
- ??</head>??
- ??<body>??
- ????<util:printBody>AAAAAAAA</util:printBody>?//结果就是怎么样相信大家猜得到!AAAAAAAA??
- ??</body>??
- </html>??
?
?