`
mzhj
  • 浏览: 227556 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JSP/Servlet/JSF:标签库的深入研究

阅读更多

 

返回值                                意义
SKIP_BODY                         表示不用处理标签体,直接调用doEndTag()方法。
SKIP_PAGE                          忽略标签后面的JSP内容。
EVAL_PAGE                         处理标签后,继续处理JSP后面的内容。 
EVAL_BODY_BUFFERED         表示需要处理标签体。
EVAL_BODY_INCLUDE           表示需要处理标签体,但绕过setBodyContent()和doInitBody()方法
EVAL_BODY_AGAIN              对标签体循环处理。 


标签库Taglib

标签被定义和分布在一个称为标签库的结构中,一个标签库是由元信息和类组成的集合:

1.标签处理器(JAVA):实现定制标签功能的Java类。

2.标签附加信息(TEI):向JSP容器提供编辑以确认标签属性和创建变量的类。

3.标签库描述器(TLD):描述单个标签和整个标签库属性的XML文档。

标签处理器(JAVA)和标签附加信息(TEI)需要定位在 JSP容器类 载入器 可以找到的地方。标签库描述器(TLD)可在URL指定的符意位置。

一、标签实现

1. 开发步骤

a.定义标签的名字、属性、声明的变量和标签体的内容。

b.编写标签库描述器TLD。

c.编写标签处理器。

d.在JSP页面中使用标签。


2. JSP页面在JSP容器中的转换步骤:

JSP页面存在三种形式:

jsp文件
java文件
class文件

a.指令元素、和向JSP容器提供转换时信息。

b.HTML行在_jspService()方法中依顺序转换到out.print()语名中。

c.脚本元素的声明被原封不动地复制到_jspService()方法外的源码中。

d.脚本元素的表达式在_jspService()方法中依顺序转换到out.print()语名中。

e.脚本元素的Scriptlet被原封不动地复制到_jspService()方法中。

f.行为元素被转换为执行其功能的运行时逻辑代码。

g.定制标签被扩展到调用其相应标签处理器中方法的Java语句中。


3.标签在JSP容器中的转换步骤:

a.JSP容器使用taglib指令元素定位标签库描述器,将页面中用到的定制标签和TLD相匹配。

b.读取标签库描述器的标签列表和每一标签相关的类名字。

c.在页面中遇到一个标签时,查找与具有指定名字的标签前缀相关的一个标签库。

d.容器使用在TLD中找到的标签结构信息生成一系列完成标签功能的Java语句。


二、标签库描述器(TLD)

标签库描述器是一个描述 整个标签库标记信息库中每个标签处理器其属性 的XML文档。

标签库描述器的DTD由一个简单的元素组成,此元素包含下列一些子元素。

1 : 整个标签库标记信息

< tlib - version > 1.0 </ tlib - version >

标签库版本号。是一个点式十进制数,最多为4组小数点分隔的数字组成。

   < jsp - version > 1.2 </ jsp - version >

标签库所需的JSP规范最低版本。例如JSP1.1

   < short - name > wentao </ short - name >

标签库的缩写名。JSP可以使用该名字作为库中标签的缺省前缀。

< uri > http: // www.wentao.com/taglibs/wentao</uri>

标签库唯一URI的元素。典型URL位置来自可下载taglib的位置。

< description > wentao Tage Liberary. </ description >

标签库描述信息。

2 : 每个标签处理器及其属性 (以displaytag-11.tld为例)

     < tag >
        
< name > table </ name >
        
< tagclass > org.displaytag.tags.TableTag </ tagclass >
        
< teiclass > org.displaytag.tags.TableTagExtraInfo </ teiclass >
        
< bodycontent > JSP </ bodycontent >
        
< info > my name is liuwentao </ info >
        
< attribute >
            
< name > list </ name >
            
< required > false </ required >
            
< rtexprvalue > true </ rtexprvalue >
        
</ attribute >
    .

    
</ tag >

tag在TLD中加入标签,描述组成库的每个标签。

 

         < name > table </ name >

name与标签库的名字前缀一起使用的标签的名字,是JSP容器唯一的标签标识 <wentao:table/>。

 

< tagclass > org.displaytag.tags.TableTag </ tagclass >

tagclass实现标签的标签处理器类的全名。

< teiclass > org.displaytag.tags.TableTagExtraInfo </ teiclass >

teiclass标签附加信息(TEI)类的全名。TEI类给出关于标签处理器创建变量及对标签属性性执行的任意有效性验证的信息。

 

         < bodycontent > JSP </ bodycontent >

bodycontent描述标签处理器如何使用标签体的内容。有三种取值:

empty:表示标签体必须为空;
JSP:表示脚本元素和模板及其它标签一样被评估。
tagdependent:体内容被原封不动写入BodyContent,其它脚本元素以源码形式出现,而不被JSP容器解释。

 

 

         < info > my name is liuwentao </ info >

info标签的人工可读描述性信息。

 

     <attribute>
            <name>list</name>
            <required>false</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>

attribute使用标签时被编码的属性信息。用于定义标签的属性。


3 :属性:

             <name>list</name>

属性的名字。

            <required>false</required>

true|false:属性在标签用到的位置是否要被编码。

            <rtexprvalue>true</rtexprvalue>

true|false:属性值能否用表达式指定。


三、标签处理器

标签处理器是通过实现JSP容器调用的一系列预定义方法执行定制标签行为的一个Java类。

标签处理器实现了标签的行为,标签处理器是Java类。

1. 标签处理器的工作方式

a.导入javax.servlet.jsp和javax.servlet.jsp.tagext包。

b.实现javax.servlet.jsp.tagext包中的Tag接口或BodyTag接口。BodyTag是Tag的子接口。

c.继承TagSupport类或BodyTagSuppoert类。它们是上述接口的缺省实现。

d.重载public int doStartTag() throws JspException方法。


2.标签处理器的接口与实现

javax.servlet.jsp.tagext.Tag是实现标签的最基本的接口。

javax.servlet.jsp.tagext.TagSupport是实现Tag接口的具体类。

通常情况下继承tagSupport类而不直接实现Tag接口通常是有益的。除了对所有必需方法提供了缺省实现外、还保存了pageContext对象及对嵌套标签的支持。

Tag接口包含4个常量 ,表示doStartTag()和doEndTag()方法可能的返回码。

         // 表示需要处理标签体。 
        int EVAL_BODY_INCLUDE = 1;

EVAL_BODY_INCLUDE 当doStartTag()返回时,指明servlet应对 标签体 进行评估。

     // 处理标签后,继续处理JSP后面的内容。
    int EVAL_PAGE = 6;

EVAL_PAGE当doEndTag()返回时,指明页面其余部分应被评估。

     //表示不用处理标签体,直接调用doEndTag()方法。
    int SKIP_BODY = 0;

SKIP_BODY当doStartTag()返回时,指明servlet应忽视标签体。

     //忽略标签后面的JSP内容。
    int SKIP_PAGE = 5;

SKIP_PAGE当doEndTag()返回时,指明页面其余部分就被跳过。


注 :body 这2个是 doStartTag()方法里面调用的。
          page 这2个是  doEndTag()方法里面调用的。


Tag接口的方法

1 :生成的servlet在请求处理器执行其它任务前首先调用此方法

  public   void  setPageContext(javax.servlet.jsp.PageContext pageContext) 

,实现类应保存上下文对象以便它可以在标签生命期中使用,从页面上下文中标签处理器可以访问所有JSP隐含对象。


2 :使用一个标答可以找到操作栈中它上面的标签

public   void  setParent(javax.servlet.jsp.tagext.Tag tag)

。在setPageContext后立即调用

  public  javax.servlet.jsp.tagext.Tag getParent()

返回父标签。

3 :在设置了页面上下文父标签开始标记中编码的属性后调用

     public   int  doStartTag()  throws  javax.servlet.jsp.JspException 

。返回码表明JSP实现servlet是否就评估标签体。


4 :当遇到结否标记时调用

     public   int  doEndTag()  throws  javax.servlet.jsp.JspException

。返回码表明JSP是否就继纽页面的其余部份。


5 :确保在页面退出前被调用

    public void release()

,释放资源并重置标签处理器状态。


TagSupport类的方法


1 :为所需的父标签处理器查找运行时标签栈。一个标签处理器可以提供其范围内子标签调用的方法 :

public static final javax.servlet.jsp.tagext.Tag findAncestorWithClass(javax.servlet.jsp.tagext.Tag tag, java.lang.Class aClass)

2 :保存和检索在id属性中指定的名字 :

    public void setId(java.lang.String string) 

3 :在本地哈希表中设置指定名字的值 :

public void setValue(java.lang.String string, java.lang.Object object)

4 :从本地哈希表中获取指定名称的值 :

public java.lang.Object getValue(java.lang.String string)

5 :从本地哈希表中删除指定名称的值 :

public void removeValue(java.lang.String string)

6 :返回哈希表中关键字的一个枚举 :

public java.util.Enumeration getValues()

 

3. 标签处理器的生命期

   前面的内容  < br >
   
< mytag:helloworld ></ mytag:helloworld >
   后面的内容

为例 :



a.生成servlet需要创建标签处理器类的一个实例。实现方式通常是调用JSP容器工厂类的一个方法,
工厂类 包含一个标签处理器实例池 以使其可重用 不再处于激活状态的对象

b.初始化标签处理器,使servlet获知其存在性。servlet通过调用标签处理器的两个方法实现此过程:

   public void setPageContext(javax.servlet.jsp.PageContext pageContext)

public void setParent(javax.servlet.jsp.tagext.Tag tag)

c.如果标签具有属性,属性的取值通过处理器提供setter方法传入到对象。属性setter方法是一个标签支持属性所需的唯一方法。

d.页面的上下文和父标签已被调置,并已具备属性。此时调用标签处理器的doStartTag()方法,该方法可以读取这些变量并执行实现标答功能所需的计算和操作。doStartTag()方法必须返回一个整型数。返回EVAL_BODY_INCLUDE则正常处理标签体,返回SKIP_BODY则忽略标签体

e.标签体被评估或忽视后调用标签处理器的doEndTag()方法,返回EVAL_PAGE则页面的其余部分被评估,返回SKIP_PAGE则servlet代码立即从_jspService()中返回。




4.体标签处理器的接口与实现

javax.servlet.jsp.tagext.BodyTag是Tag的子接口。

javax.servlet.jsp.tagext.BodyTagSupport是实现BodyTag类。




BodyTagSupport 有一个这样的方法 :

 public void setBodyContent(javax.servlet.jsp.tagext.BodyContent bodyContent) 


BodyContent是javax.servlet.jsp.JspWriter的子类,但与其父类有所区别。

public abstract  class  BodyContent extends javax.servlet.jsp.JspWriter



BodyContent对象的内容不自动写了入servlet的输出流,而是积累在一字符串缓存中。当标签体完成后 其对象 仍可在doEndTag()方法中可以应用,由getString()或getReader()方法操作。并在必要时修改及写入恢复的JspWriter输出流。

BodyContent类的方法

  public void flush() throws java.io.IOException

复写JspWrite.flush()方法以便它总是产生溢出。

public void clearBody()

重置BodyContent缓存为空。

    public abstract java.io.Reader getReader();

返回Reader读取体内容。

    public abstract java.lang.String getString();

返回包含体内容的一个字符串。

    public abstract void writeOut(java.io.Writer writer) throws java.io.IOException;

将体内容写入指定输出。

 public javax.servlet.jsp.JspWriter getEnclosingWriter()

返回栈中下一个更高的写入者对象(可能是另一个BodyContent对象)。


BodyTag接口定义了一个新的整型常量



EVAL_BODY_TAG当doStartTag()返回时,使得新的BodyContent对象被创建并与此标签处理器相关联。当doAfterBody()返回时,使得JSPservlet在修改完此标签控制的任意变量后再次评估体。

BodyTag接口的方法

void setBodyContent(javax.servlet.jsp.tagext.BodyContent bodyContent);

在当前JspWriter已被写入,一个新的BodyContent在被创建后由Jspservlet调用,它发生在doStartTag()之后。

 void doInitBody() throws javax.servlet.jsp.JspException;

setBodyContent()之后,体被评估前调用的生命期方法。如果多次评估体,此方法只调用一次。

 public int doAfterBody() throws javax.servlet.jsp.JspException 

体被评估后,BodyContent写入者仍处于激活状态时调用的生命期方法。此方法必须返回EVAL_BODY_TAG或SKIP_BODY,若返回EVAL_BODY_TAG时体再次被评估。

BodyTagSupport类的方法

  public int doStartTag() throws javax.servlet.jsp.JspException 

复写TagSupport中的doStartTag()方法。

 public int doEndTag() throws javax.servlet.jsp.JspException

调用TagSupport中的doEndTag()方法,返回结果。

public void setBodyContent(javax.servlet.jsp.tagext.BodyContent bodyContent)

在一保护成员变量bodyContent中保存新的体内容对象,子类可直接访问此对象。

public void doInitBody() throws javax.servlet.jsp.JspException 

缺省什么都不做。被需要执行初始化的子类所复写。

public int doAfterBody() throws javax.servlet.jsp.JspException

每次体被评估后由JSPservlet调用,体内容对象仍处于激活状态。返回SKEP_BODY或EVAL_BODY_TAG则体再次被评估

 public void release() 

设置bodyContent对象为null,然后调用super.release()。

public javax.servlet.jsp.tagext.BodyContent getBodyContent()

返回bodyContent变量。子类已经可以访问保护变量,但此方法允许无关的标签处理类对此体内容发送输出。

public javax.servlet.jsp.JspWriter getPreviousOut() 

在bodyContent变量上调用getEnclosingWriter()并返回结果的简便方法。

5.体标签处理器的生命期

a.生成servlet需要创建标签处理器类的一个实例。实现方式通常是调用JSP容器的工厂类的一个方法,工厂类包含一个标签处理器实例池以使其可重用不再处于激活状态的对象。

b.初始化标签处理器,使servlet获知其存在性。servlet通过调用标签处理器的两个方法实现此过程:setPageContext(PageContextctx)和setParent(Tagparent)。

c.如果标签具有属性,属性的取值通过处理器提供setter方法传入到对象。属性setter方法是一个标签支持属性所需的唯一方法。

d.页面的上下文和父标签已被调置,并已具备属性。调用标签处理器的doStartTag()方法,该方法可以读取这些变量并执行实现标答功能所需的计算和操作。

doStartTag()方法必须返回一个整型数。

返回EVAL_BODY_TAG则正常处理标签体(跳到e);

返回SKIP_BODY则从初始JSP页面中直到此标签结束标记处的内容均被忽略。(跳到f)

e.如果返回EVAL_BODY_TAG时,则正常处理标签体。

e1.在栈中保存当前的JspWriter对象,创建新的BodyContent对象,并将其置为JSP页面的out对象保存在上下文范围内名为name的属性中。并调用它的setBodyContent()方法。

e2.调用doInitBody()方法进行初始化。

e3.处理标签体。将输出写入BodyContent对象中,此过程依赖于TLD的标签元素,有三种可能取值。

e4.调用doAfterBody()方法,将体内体内容写入JspWriter,可如下实现:

JspWriterout = bodyContent.getEnclosingWriter();
out.println(bodyContent.getString());
// bodyContent.writeOut(out);
bodyContent.clear();

e5.doAfterBody()方法返回两种可能:

返回EVAL_BODY_TAG时,再对标签体进行评估,这是数组和枚举被循环处理的典型情况。

返回SKIP_PAGE时,继续页面的其余部份。

e6.体内容完成,因此创建它的过程被反向:

调用pageContent.popBody()方法检索前面的JspWriter对象。

将写入者设置回out隐含对象。

f.标签体被评估或忽视后调用doEndTag()方法,允许标签处理器像输出流发回内容。

返回EVAL_PAGE则页面的其余部分被评估;

返回SKIP_PAGE则servlet代码立即从_jspService()中返回。

g.此时体的内容在受保护的bodyContent对象中仍然可用。

可以将它写入servlet输出流中:

JspWriterout=pageContext.getOut();

out.println(bodyContent.getString());

或者

bodyContent.WriteOut(pageContext.getOut());


6.标签附加信息类


四、标签指令

taglib指令元素的目的是指定TLD的位置,设置在页面上与标签区分开来的一个短别名。

语法:

<% @taglib uri = " /helloworld "  prefix = " mytag " %>

属性:prefix:用于标识标签库的唯一标识。uri:标签库本身的URI。

uri不必指向一个实际文件,它是JSP容器可以在web.xml中查找实际文件位置的唯一标识符。

分享到:
评论

相关推荐

    Java代码中使用JSP/JSF表达式语言EL

    Java代码中使用JSP/JSF表达式语言(EL,Expression Language)是Web开发中的一个核心概念,它允许开发者在页面上动态地访问和操作JavaBean或其他数据源的...通过实践和深入研究,开发者可以更好地掌握这一强大的工具。

    JSF标签应用实例

    JSF(JavaServer Faces)是Java平台上用于构建用户界面的组件模型框架,它提供了一种声明式的方式来创建和管理Web应用...通过深入研究和运行这个项目,开发者不仅可以理解JSF的基础,还能进一步掌握JavaWeb开发的技能。

    《Java Web开发教程——入门与提高篇(JSP+Servlet)》附赠电子资料——框架基础及实例

    根据提供的文档信息,我们可以深入探讨该附赠电子资料中涵盖的主要知识点和技术框架,特别是针对Struts2、JSF、Hibernate、iBATIS以及JPA等内容。 ### 1. Java Web开发基础 #### 1.1 JSP (Java Server Pages) JSP...

    JSF编程实战导航-随书源代码

    6. **库文件**:虽然在描述中提到,为了减小文件大小,`lib`目录下的`.jar`包被删除了,但JSF应用程序通常依赖于这些库,如Servlet API、EL API、JSF实现(如MyFaces或Mojarra)和其他第三方库。如果在运行时遇到...

    servlet官方源码

    通过深入研究servlet官方源码,开发者不仅可以了解Servlet的工作机制,还能掌握如何优化性能,处理并发,以及更好地集成其他Java Web技术,如JSP、JSF等。同时,这也有助于理解Spring MVC等高级框架的底层原理,提升...

    JSP.zip_JSP考试

    **JSP(Java Server Pages)技术详解** JSP(Java Server Pages)是Java平台上的一个核心Web开发...通过深入研究JSP,开发者能够构建高效、可扩展的Web应用。希望这份资料能帮助你顺利通过JSP考试,提升Web开发技能。

    javax-servlet源码包和jar文件

    通过深入研究`javax.servlet`和`javax.servlet.jsp`的源码,开发者能够更好地掌握Web应用的构建和运行机制,提升解决问题的能力。同时,通过实践和阅读源码,可以学习到如何有效地管理请求响应、处理并发、优化性能...

    JSF实战 练习 开发

    - **深入研究**: 学习JSF的高级特性,如事件处理、导航规则和国际化配置等。 - **工具支持**: 选择合适的开发工具(如Eclipse、NetBeans等)来辅助开发过程。 #### 六、总结 综上所述,JSF不仅为Web开发带来了便利...

    JSP应用开发详解第三版源代码

    9. **JSP 2.0及更高版本的特性**:包括引入了EL和JSTL,支持JavaServer Faces(JSF)组件,以及增强了对Servlet 2.4及更高版本的支持。 10. **Web容器**:JSP应用程序需要在Web容器(如Tomcat、Jetty等)中运行,...

    jsf demo 各种实例

    通过对"jsfdemo"中的例子进行实践和研究,开发者可以深入理解JSF的工作原理,掌握如何构建和部署JSF应用,并熟悉如何利用Eclipse和Tomcat这样的工具链来支持开发流程。同时,也可以了解到如何结合其他Java EE技术,...

    JSP程序设计书本源代码(第2版)

    8. **JSTL和JSF**:JSP Standard Tag Library(JSTL)是标准标签库,可以提高代码可读性和可维护性;JavaServer Faces(JSF)是一种组件化开发框架,简化了UI开发。 9. **JSP生命周期和事件监听器**:讨论了JSP页面...

    [聊天留言]泽风Jsp留言本_zefengbook.zip

    5. **论文**:这可能意味着该留言本项目可以作为研究或论文写作的基础,学生可以基于此进行更深入的研究,例如优化性能、改进用户体验或增加新功能。 【压缩包子文件的文件名称列表】:“[聊天留言]泽风Jsp留言本_...

    java web 开发 api大全 chm文档

    【Java Web开发API大全CHM文档】集合了多个与Java EE相关的API和技术,包括Java EE 5和6的英文规范,Tomcat 6.0的中文文档,以及JSP...通过深入研究和实践,你可以更好地利用Java EE平台构建高效、可扩展的企业级应用。

    JSP源码——866ccv3.0jtb.zip

    【JSP源码——866ccv3.0jtb.zip】是一个包含JSP(JavaServer Pages)源代码的压缩文件,很可能是一...通过深入研究这些源代码,开发者可以学习到如何使用JSP构建实际的Web应用程序,以及如何组织和管理复杂的Web项目。

    jsf学习实例

    JavaScript Server Faces(JSF)是Java平台...通过深入研究这个实例,你可以了解到JSF如何将前端和后端结合,以及如何创建、配置和运行一个完整的JSF应用。这将有助于提升你对JSF的理解,为实际项目开发打下坚实基础。

    JSP程序设计精彩实例

    **JSP程序设计精彩实例** 在IT行业中,JavaServer Pages(JSP)是一种广泛使用的动态网页技术,由Sun ...通过深入研究和分析这些实例,可以更好地理解JSP的工作原理,以及如何有效地利用其特性构建高质量的Web应用。

    JSF 应用 在线购物系统

    3. **Eshopf**:这个版本是使用JSF框架构建的,其核心在于将原来的Servlet替换成了JSF Servlet,并对用户界面进行了重构。 #### Eshopf版本的技术特点 Eshopf版本采用了JSF框架,这使得系统的开发变得更加高效且...

    myfaces-example-tiles-1.1.6.rar_Tiles_jsf myfaces_jsf tiles exam

    **JSF(MyFaces)与Tiles框架整合应用** `myfaces-example-tiles-1.1.6.rar` 是一个示例项目,它...通过深入研究这个示例,开发者可以更好地理解如何在实际项目中结合使用JSF和Tiles,提升Web应用的结构化和可维护性。

    JSF资源---精心收集,奉献给大家

    **JSF(JavaServer Faces)** 是Java平台上的一种开源Web应用程序框架,主要用于构建用户界面。它简化了前端和后端的交互...通过深入研究其中的内容,可以提升开发技能,更好地运用JSF来构建高效、可靠的Web应用程序。

Global site tag (gtag.js) - Google Analytics