JSP自定义标签

JSP自定义标签

1自定义标签功能

标签:标签是一个可重复使用的单元,用于执行程序中的重复性任务. 例如html中的< h1>,< div>.

自定义标签:指的是用户定义的标签,说得专业点.它是一个可重复使用的组件,并封装了java代码.是用户定义的JSP语言元素.举个例子:用户定义一个< welcome>标签,作用是显示欢迎消息.

这个自定义标签可以在对应项目的JSP页面中使用.

自定义标签功能可通过创建可重用组件来减少JSP中复杂、重复的业务逻辑代码。这些组件可用于其他应用程序。javax.servlet.jsp.tagext 包定义了开发自定义标签 的类和接口。可使用此包的类和接口创建标签处理程序,这些程序可实现带属性的自定义标签、带主体的自定义标签、嵌套自定义标签。

引例:
  1. 导入jsp.api

  2. 定义< welcome>标签,WelcomeTag.java。

    public class WelcomeTag  extends TagSupport {
        public int doStartTag() throws JspException{
            try{
                JspWriter out= pageContext.getOut();
                out.print("Welcome to custom tags");
            }
            catch (Exception e){
                e.printStackTrace();
            }
            //skip_body隐含零,不输出开始标签和结束标签之间的内容
            return SKIP_BODY;
        }
    }
    
  3. 创建tld文件,将WelcomeTag.java封装成一个标签.(tld文件,配置文件的一种,eclipse创建xml文件时修改后缀为tld,idea可以点击创建xml文件类型后选择JSP Tag文件直接创建)

  4. welcome.tld

    <tag>
    <!--    标签名-->
        <name>welcome</name>
    <!--    定义标签的类-->
        <tag-class>Tag.WelcomeTag</tag-class>
    <!--     标签体为空-->
        <body-content>empty</body-content>
    </tag>
    
  5. 使用自定义的< welcome>标签,welcome.JSP.prefix为定义taglib的名字,也就是调用自定义标签时的前缀。uri为标签库的唯一标识。

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ taglib prefix="t" uri="/WEB-INF/welcome.tld"%>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <t:welcome/>
    </body>
    </html>
    
  6. 输出

image-20221110214727953

1.1自定义标记API

自定义标签 API 由 javax.servlet.jsp.tagext 包的类和接口组成.javax.servlet.jsp.tagext 包中定义的接口有:

  • Tag:定义在标签的生命周期中,可以由 JSP 实现类调用的方法。标签处理程序实现这些方法以执行自定义操作。Tag接口中定义的方法有doEndTag()、doStartTag()、release()、 setPageContext()、setParent()、getParent()。
  • IterationTag:扩展了 Tag 接口,除 Tag 接口中定义的方法外,还定义了 doAfterBody() 方法。此方法可重新计算自定义标签的主体内容
  • BodyTag:扩展了 IterationTag接口,定义了可让标签处理程序操作自定义标签主体内容的方法。此接口定义了 doInitBody() 和 setBodyContent() 方法。doInitBody()方法可让标签处理程序准备用于计算的标签。setBodyContent() 方法可让标签处理程序操作标签的主体内容

javax.servlet.jsp.tagtext 包的各种类:

描述
BodyContentJSPWriter 类的子类,表示标签的主体内容。
TagSupport作为标签处理程序的基类并实现空标签。
BodyTagSupport实现 jBodyTag 接口。此类用于开发带主体的自定义标签
TagData表示属性及其值。
TagInfo表示 TLD 文件的元素中指定的信息。JSP 将 JSP页面转换为 servlet 时使用此类。
TagLibraryInfo表示 TLD 文件的信息,例如它定义的标签和版本信息。
TagVariableInfo表示自定义标签的变量的相关信息。

下表描述了可在标签处理程序中实现的各种方法:

方法描述
public int doStartTag()是由 Tag 接口定义的。当遇到自定义标签的开始标签时调 用此方法。doStartTag() 方法返回 SKIP_BODY 值指定跳过主体内容的处理。此方法还可返回 EVAL_BODY_INCLUDE 值指定应处理标签的主体内容。举个例子,welcome标签为自定义标签,< welcome>欢迎</ welcome>,如果返回值是SKIP_BODY,则"欢迎"这个中间体不会输出,返回值是 EVAL_BODY_INCLUDE ,则会输出.
public void release()是由 Tag 接口定义的。调用此方法可让标签处理程序释放其部分资源。
doAfterBody()是由 BodyTagSupport 类实现的。计算主体标签后调用此方法。doStartTag() 方法返回 EVAL_BODY_AGAIN 值指定应重新计算主体内容。doStartTag() 方法返回 SKIP_BODY 值指定跳过主体内容的计算
public int doEndTag()是由 Tag 接口定义的。当遇到自定义标签的结束标签时调用此方法。doEndTag() 方法返回 EVAL_PAGE 值以处理剩余的 JSP 页面或返回 SKIP_PAGE 值以跳过剩余页面的处理

javax.servlet.jsp 包包含 PageContext 类,该类表示 JSP 页面并将 JSP 页面的信息提供给 标签处理程序。PageContext 类定义可在标签处理程序中调用来访问 JSP 页面各种隐式对象的方法。下表描述了 PageContext 类的一些重要方法:

方法描述
public abstract JspWriter getOut()返回 JSP 隐式对象 out。
public abstract ServletRequest getRequest()返回 JSP 隐式对象 request。
public abstract ServletResponse getResponse()返回 JSP 隐式对象 response。
public abstract HttpSession getSession()返回 JSP 隐式对象 session。
public abstract Exception getException()返回 JSP 隐式对象 exception。
public abstract ServletContext getServletContext()返回 JSP 隐式对象 application。
public abstract ServletConfig getServletConfig()返回 JSP 隐式对象 config。
public abstract Object getPage()返回 JSP 隐式对象 page。
1.2自定义标签

自定义标签的类型有

  • 带属性的自定义标签
  • 带主体的自定义标签
  • 嵌套自定义标签
1.2.1带属性的自定义标签

html中img标签有src属性等,而用户自定义标签也可以带有属性值。可使用各种属性定制自定义标签执行的功能。每个自定义属性 (attribute) 需定义一个属性 (property)。可使用 getXXX() 和 setXXX() 方法访问和设置标签 处理程序类中的属性

举个例子,自定义< goods>标签

<t:goods type='books'></t:goods>

要实现此标签,需在标签处理程序类中定义属性 (property) copyright。还需定义 setCopyright() 和 getCopyright() 方法分别设置和访问该属性。可用以下代码段在标签处理程序中声明属性:

public class Goods extends TagSupport {
    String type;
    //实现特定功能
    //获取Type值
    public String getType(){
        return this.type;
    }
    //set type value
    public void setType(String type){
        this.type=type;
    }
}

要在 TLD 文件中定义带属性的自定义标签,需指定自定义标签包含 TLD 文件的属性元素中的属性。 该属性元素包含以下子元素:

  • name:指定属性名称
  • required:指定属性是必需的还是可选的。值 true 表示 JSP 页面中必须有此属性值。
  • rtexprvalue:指定运行时表达式(例如 JSP 表达式)是否可用于此属性。可能的值有 true、false、yes、no。

例如上面的goods标签,想要用自定义标签的属性,需要在tld文件配置

<tag>
    <name>Goods</name>
    <tag-class>Tag.Goods</tag-class>
    <body-content>empty</body-content>
    <attribute>
        <name>type</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
</tag>

以上代码配置了Goods用户自定义标签,同时配置了属性值type。required值为true意味着在使用Goods标签时type属性必须使用。

1.2.2带主体的自定义标签

主体标签中括住文本,js,JSP表达式等其它jsp组件的自定义标签称为带主体的自定义标签。

举个例子

< t:welcome>hello </ t:welcome>

开始标签和结束标签中有文本,带主体的自定义标签之一.

在tld文件中配置标签时,可以指定自定义标签是否包含主体,当包含主体时应该在< tag>中使用下面语句.

<body-content>JSP</body-content> 

不包含主体时,< body-content>内容为empty.表示容器将不会计算主体内容.例如上面welcome标签例子中,hello将不会被处理输出到页面上.

<body-content>empty</body-content> 

具体配置例子为

<tag> 
 <name>HelloTag</name> 
 <tag-class>hello.HelloTagHandler</tag-class> 
 <body-content>JSP</body-content> 
</tag> 

带主体的自定义标签中,主体可以通过调用其 doAfterBody() 方法中 BodyTagSupport 类 的 getBodyContent() 方法获取.这个方法将返回bodycontent对象.调用其 doAfterBody() 方法中 BodyTagSupport 类 的 getBodyContent() 方法获取具体主体内容.

下面是获取主体内容后并打印输出的例子

public int doAfterBody() throws JspException 
 { 
 try 
 { 
 /* 获取 BodyContent的实例 */ 
 BodyContent bc = getBodyContent(); 
//获取主题字符串内容
 String body = bc.getString(); 
 JspWriter out = bc.getEnclosingWriter(); 
 out.println(body.toUpperCase());
 ......
1.2.3嵌套的自定义标签

嵌套标签,举个html例子方便理解

<div><h1>hello</h1></div>

这就是一个嵌套标签,h1标签嵌套在div标签内.一个标签的主体部分含有其它标签,即为嵌套标签.外围标签为父标签.里面标签为子标签.

子标签使用 Tag 接口的 getParent() 方法 或 TagSupport 类的 findAncestorWithClass() 方法与父标签进行通信。

嵌套的自定义标签例子,子标签返回父标签属性值,如果为true则输出主体内容.

嵌套标签

<pdtd:ParentTag condition= “true” >
 <chtd:ChildTag> 
 The expression evaluates to true 
 </chtd:ChildTag> 
</pdtd:ParentTag> 

父标签代码

import javax.servlet.jsp.tagext.*; 
import class ParentTag extends TagSupport 
{ 
 private boolean condition; 
public int doStartTag() 
 { 
 return EVAL_BODY_INCLUDE; 
 } 
 public void setCondition (Boolean condition) 
{ 
 this.condition = condition; 
} 
public boolean getCondition() 
{ 
 return condition; 
} 
} 

在上述代码中,标签接受属性 condition。doStartTag() 方法返回 EVAL_BODY_INCLUDE,它指定要计算的标签主体

子标签代码

import javax.servlet.jsp.tagext.*; 
import class ChildTag extends TagSupport 
{ 
 
public int doStartTag() 
 { 
 ParentTag parent = (ParentTag) getParent(); 
/* 使用getparent()方法获取父标签 */ 
boolean condition = parent.getCondition(); 
/* 使用getCondition()方法获取父标签的condition属性 */ 
if(condition) 
{ 
 return EVAL_BODY_INCLUDE; 
} 
else 
{ 
 return SKIP_BODY; 
} 
}/* End doStartTag() */ 
} 

condition为true时返回EVAL_BODY_INCLUDE,为flase时SKIP_BODY.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值