声明:本文由本人将多篇文章整合而成,非本人原创。
?
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 页面使用自定义标签
?
- 扩展TagSupport
??? ???
说明:
??? ??? ??? ???
一般不会去实现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;?// 不包含主体内容??
- ????}??
- }??
?
- 写自定义Tag 的tld 文件
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 |
标签属性的信息 |
??????????? 这些呢,是为以后高级内容说要提到的!
- web.xml 中指定你的tld 文件
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>?
- 页面部署:mytag.jsp
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>??
?
?