自定义标签(JSTL)

这里引入两个接口JspTag SimpleTag和一个实现类SimpleTagSupport 它们的关系是 JspTag是根接口,没有定义任何方法,SimpleTag接口是JspTag的子接口 SimpleTagSupportSimpleTag的实现类
还引入两个异常处理类JspException JspTagException

自定义标签步骤:

1.创建标签的处理类
2.创建标签库描述文件(.tld)
3. 在JSP页面中使用标签

1.空标签的开发

实现SimpleTag接口方式

五个生命周期方法说明:
  1. setJspContext设置JspContext对象
  2. setParent设置父标签对象
  3. setJspBody若标签带标签体(标签体不能包含JSP脚本),容器调用该方法,将标签体内容存在到JspFragment中
  4. getParent返回当前标签的父标签
  5. doTag核心方法 由容器调用完成简单标签的操作
    五个生命周期调用顺序:setJspContext -> setParent -> setJspBody -> doTag
1.创建标签的处理类
package com.mytag;

import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.JspTag;
import javax.servlet.jsp.tagext.SimpleTag;
import java.io.IOException;

public class MyFirstTag implements SimpleTag {
    JspContext jspContext = null;
    JspTag parent = null;
    public void doTag() throws JspException, IOException {
        jspContext.getOut().print("这是我的第一个标签");
    }
    public void setParent(JspTag parent){
        this.parent = parent;
    }
    public JspTag getParent(){
        return parent;
    }
    public void setJspContext(JspContext jspContext){
        this.jspContext = jspContext;
    }
    public void setJspBody(JspFragment body){
    }
}
//必须实现上面5个生命周期方法
2.创建标签库描述文件(.tld)

该文件放在web-info目录下

<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" version="2.0">
    <tlib-version>1.0</tlib-version>
    <short-name>TagExample</short-name>
    <uri>http://www.mydomain.com/sample</uri>
    <tag>
        <name>firstTag</name>
        <tag-class>com.mytag.MyFirstTag</tag-class>
        <body-content>empty</body-content>
    </tag>
</taglib>

说明:

  1. uri设置地址自定义,需要在jsp的taglib指令中引入该地址,name为自定义标签名tag-class表示标签处理类的路径
  2. 这里body-content表示标签体为空(还不能回车换行)
  3. 每个tld文件里uri的值是唯一的,可以有多个tag标签,但是name值必须不一样
3. 在JSP页面中使用标签
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="demo" uri="http://www.mydomain.com/sample" %>
<html>
<head>
    <title>第一个标签</title>
</head>
<body>
<p>您好!!!</p>
<demo:firstTag />
</body>
</html>

说明:

  1. prefix表示标签前缀,uri对应tld文件中的uri标签内容

2.带属性标签的开发

继承SimpleTagSupport类实现

1.创建标签的处理类
package com.mytag;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;

public class MathTag extends SimpleTagSupport {
    double x;
    public void setX(String x){
        double num = 1;
        try{
            num = Double.parseDouble(x);
            System.out.println("值获取成功"+num);
            this.x=num;
        }catch (NumberFormatException nfe){
            System.out.println("值获取失败,赋值为默认值");
            this.x = num;
        }
    }
    public void doTag() throws JspException, IOException{
        JspWriter out = getJspContext().getOut();
        out.print(x+ " 的平方根是:"+ x*x);
    }
}

说明:

  1. 这里setX表示,设置该标签的属性x的值(由jsp页面中标签的属性值传递而来)
  2. 继承SimpleTagSupport类只需要实现doTag方法即可
2.创建标签库描述文件(.tld)
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" version="2.0">
    <tlib-version>1.0</tlib-version>
    <short-name>TagExample</short-name>
    <uri>http://www.mydomain.com/sample</uri>
    <tag>
        <description>Compute Square Root</description>
        <name>sqrt</name>
        <tag-class>com.mytag.MathTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <name>x</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
</taglib>

说明:

  1. 标签的每一个属性都要在标签attribute中定义属性名
  2. 这里设置属性名为x而且是必须添加该属性
  3. rtexprvalue表示是否能接受请求时表达式的值,默认为false
body-context的值说明:
  1. empty表示是标签不带标签体,不能包含空格和换行
  2. scriptless表示标签体中不能包含JSP脚本元素(<%%> <%=%>等)
  3. tagdependent 表示容器不会执行标签体,而是在请求时把它传递给标签处理类,由标签处理类决定处理标签体,比如放入SQL语句
3. 在JSP页面中使用标签

使用方式与前面一致

说明:

  1. 属性值可以是常量 EL表达式 也可以时JSP表达式<jsp:attribute name="属性名">属性值</jsp:attribute>. 对于由属性标签必须要做三件事:
    1.1 必须在标签处理类中声明一个变量存放属性值
    1.2 如果属性不是必需的,则必需提供默认值,或者在代码处理相应的null值
    1.3 对于每一个属性都必须实现适当的修改方法(set属性名())

3.带标签体的标签

通过继承SimpleTagSupport类可以实现
说明:

  1. 通过getJspContext()方法获得JspContext对象
  2. 通过invoke(Writer out)执行标签体中的代码 并将结果发送到Writer对象,如果将结果输出到JSp页面则参数为null比如geJspBody().invoke(null); 书写在doTag方法体里

迭代标签

即通过给invoke()方法传入StringWriter()对象,然后通过for循环实现
在doTag里

StringWriter sw = new StringWriter();
getJspBody().invoke(sw );
String text = sw.toString();//获取标签体中的内容
for(int i=1;i<=count;i++){
	out.print("<h"+i+">"+text+"</h"+i+">");
}//count为属性传递过来的值,表示迭代次数

4.在标签体中使用EL表达式

在标签体里面使用EL表达式来访问doTag里面的添加的内容

getJspContext().setAttribute("product","苹果手机");
getJspBody().invoke(null);

在标签体中${product}即可显示

5.使用动态属性

在简单标签中还可以处理动态属性(不需要在TLD文件中定义的属性)
需要标签实现类实现DynamicAttribute接口,还接口只有一个方法,该方法来处理动态属性.方法是public void setDynamicAttribute(String uri,String localName,Object value) throws JspException参数uri表示属性的命名空间,localName表示动态属性名,value表示属性值
使用:

  1. 首先实现DynamicAttribute 接口
  2. 在标签实现类首先定义一个String类型的字符串(这里是output),用来接受返回的字符
  3. 实现setDynamicAttribute(String uri,String localName,Object value)方法
  4. 在setDynamicAttribute的方法体 通过if else 对传递过来的参数进行判断,然后给output赋值
  5. 最后将output对象作为参数传递给invoke方法即可
    注意:
  6. 当传递过来的属性在tld中没有定义才会调用DynamicAttribute方法 ,静态的会按照tld中的定义正常调用set属性名()每一个动态属性都会调用DynamicAttribute方法一次
  7. 在tld文件中动态属性需要添加一个标签<dynamic-attributes>true</dynamic-attributes>
  8. 动态属性不能使用EL表达式指定
发布了103 篇原创文章 · 获赞 5 · 访问量 2237

猜你喜欢

转载自blog.csdn.net/weixin_42452726/article/details/103103671
今日推荐