当前位置: 代码迷 >> JavaScript >> JSP自定义标签学习【轻便了解JSP自定义标签过程】
  详细解决方案

JSP自定义标签学习【轻便了解JSP自定义标签过程】

热度:311   发布时间:2012-09-20 09:36:50.0
JSP自定义标签学习【轻松了解JSP自定义标签过程】

声明:本文由本人将多篇文章整合而成,非本人原创。

?

JSP处理逻辑:

JSP标签其实,是由服务端的Java类执行一些处理后,翻译成HTML,然后返回 给客户端,渲染展示出来。

附图:

?

JSP具体处理步骤如下:

?

1 .在JSP 中引入标签库:

?


1

<% @ taglib prefix=”taglibprefix” uri=”tagliburi” %>

2 .在JSP 中使用标签库标签

3Web 容器根据第二个步骤中的prefix ,获得第一个步骤中声明的tagliburi 属性值

4Web 容器根据uri 属性在web.xml 找到对应的元素

5 .从元素中获得对应的元素的值

6Web 容器根据元素的值从WEB-INF/ 目录下找到对应的.tld 文件

7 .从.tld 文件中找到与tagname 对应的元素

8 .凑元素中获得对应的元素的值

9Web 容器根据元素的值创建相应的tag handle class 的实例

10. Web 容器调用这个实例的doStartTag/doEndTag 方法完成相应的处理

?

?

自定义标签的 步骤如下

  1. 扩张TagSupport
  2. 写自定义Tagtld 文件
  3. web.xml 中指定你的tld 文件
  4. 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 代码

?

  1. package?com.mercyblitz;??
  2. import?java.io.IOException;??
  3. import?javax.servlet.jsp.JspException;??
  4. import?javax.servlet.jsp.JspWriter;??
  5. import?javax.servlet.jsp.tagext.TagSupport;??
  6. ??
  7. public?class?MyTags?extends?TagSupport?{??
  8. ????public?int?doStartTag()throws?JspException??
  9. ????{??
  10. ????????JspWriter?out=pageContext.getOut();??
  11. ????????try??
  12. ????????{??
  13. ????????????out.println("Hello,World");?// 页面中显示的内容??
  14. ????????}catch(IOException?e)??
  15. ????????{??
  16. ????????????throw?new?JspException(e);??
  17. ????????}??
  18. ????????return?SKIP_BODY;?// 不包含主体内容??
  19. ????}??
  20. }??

?

  • 写自定义Tagtld 文件

xml 代码

?

  1. <?xml?version="1.0"?encoding="UTF-8"?>??
  2. <!DOCTYPE?taglib?PUBLIC?"-//Sun?Microsystems,?Inc.//DTD?JSP?Tag?Library?1.2//EN"?"web-jsptaglibrary_1_2.dtd"?>??
  3. <taglib>??
  4. ??<tlibversion>tlibversion</tlibversion>??<!--? 你自定义标签的版本数?-->??
  5. ??<jsp-version>1.2</jsp-version>??<!--? 指定你的JSP 版本,扩张标签是在JSP1.2 之后兼容的?--?>??
  6. ??<shortname>shortname</shortname>?<!--? 标签的简写?-->??
  7. ??<tag>??
  8. ????<name>tags</name>??<!--? 标签名字?-->??
  9. ????<tagclass>com.mercyblitz.mytags</tagclass>??<!--? 指定你的标签的类?-->??
  10. ??</tag>??
  11. </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 代码

?

  • ?
    1. <?xml?version="1.0"?encoding="UTF-8"?>??
    2. <web-app?version="2.4"???
    3. ????xmlns="http://java.sun.com/xml/ns/j2ee"???
    4. ????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"???
    5. ????xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee???
    6. ????http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">??
    7. ????<welcome-file-list>??
    8. ???????<welcome-file>/WEB-INF/mytag.jsp</welcome-file>?<!--? 设置欢迎页面?-->??
    9. ????</welcome-file-list>??
    10. ????<jsp-config>??
    11. ??????????<taglib>??
    12. ????????<taglib-uri>http://mercyblitz.blog.ccidnet.com/taglibs.tld</taglib-uri>?<!--? 设置自定义标签的uri (不一定存在,但是一定要唯一), 为页面的部署做好准备??
    13. ????????<taglib-location>/WEB-INF/taglibs.tld</taglib-location>??<!-- 定位你的tld 文件的相对路径?-->??
    14. ??????</taglib>??
    15. ????</jsp-config>??
    16. </web-app>?
  • 页面部署:mytag.jsp

html 代码

?

  • ?
    1. <%@?page?language="java"?import="java.util.*"?pageEncoding="GBK"%>??
    2. <%@?taglib?uri="http://mercyblitz.blog.ccidnet.com/taglibs.tld"?prefix="out"?%>??
    3. <html>??
    4. ??<head>??
    5. ????<title>mytag.jsp</title>??
    6. ??</head>????
    7. ??<body>??
    8. ????<out:tags/>? <!-- 页面执行的结构,就是:? Hello,World -->
    9. ??</body>??
    10. </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
容器是在调用标记的doAfterBodydoEndTag 方法之间调用PageContent.popBody() 方法的
注意请不要在doEndTag() 后面去访问BodyContent, 因为servlet 容器在调用标记处理程序的doEndTag() 方法为 止,servlet 容器可能已经再次使用了该标记的主题内容, 使用doEndTag 方法访问自己主体内容的标记, 可能会访问到其他标记的主体内容, 或者可 能访问到空值, 这样就导致了不确定的行为

BodyTagSupport
, 实现BodyTag 接口的类
??? public BodyContent getBodyContent();//
返回主题内容
??? public JspWriter getPreviousOut();//
返回前一个out 对象
???

写个东西来说明以下:
打印出主体内容!

java 代码

?

  1. import?java.io.IOException;??
  2. ??
  3. import?javax.servlet.jsp.JspException;??
  4. import?javax.servlet.jsp.tagext.BodyTagSupport;??
  5. ??
  6. public?class?PrintBodyTag?extends?BodyTagSupport?{??
  7. ????public?int?doAfterTag()throws?JspException??
  8. ????{??
  9. ????????try??
  10. ????????{?????????
  11. ????????????this.getBodyContent().writeOut(getPreviousOut());// 上面讲的理论!??
  12. ????????}catch(IOException?e)??
  13. ????????{??
  14. ????????????throw?new?JspException(e);??
  15. ????????}??
  16. ????????return?SKIP_BODY;??
  17. ????}??
  18. }??

部署tld 文件

xml 代码

?

  1. ......??
  2. ??<tag>??
  3. ????<name>printBody</name>??
  4. ????<tag-class>PrintBodyTag</tag-class>??
  5. ??????
  6. ??</tag>??
  7. ??......??

页面加载:
html
代码

?

  1. <%@?page?language="java"?import="java.util.*"?pageEncoding="ISO-8859-1"%>??
  2. <%@?taglib?uri="http://www.eimhe.com/taglibs/util.tld"?prefix="util"%>??
  3. <!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN">??
  4. <html>??
  5. ??<head>??
  6. ????<title>My?JSP?'tag.jsp'?starting?page</title>??
  7. ??</head>??
  8. ??<body>??
  9. ????<util:printBody>AAAAAAAA</util:printBody>?// 结果就是怎么样相信大家猜得到!AAAAAAAA??
  10. ??</body>??
  11. </html>??

?


?

  相关解决方案