javaweb -自定义标签(传统方式)

一般我们说自定义标签是指JSP自定义标签。自定义标签在功能上逻辑上与javaBean 类似,都封装Java 代码。自定义标签是可重用的组件代码,并且允许开发人员为复杂的操作提供逻辑名称。
JSP开发人员使用标签库创建标签.标签库是按照功能或实现进行分组的自定义标签的集合。
网络上常见的CMS内容管理系统都是采用模板的形式来实现,基本上所有的CMS系统都有一套自己的模板标签书写方法,简称自定义标签。

传统方式

在这里插入图片描述

自定义标签
        传统方式(jsp1.1):实现Tag接口
        简单方式(jsp2.0):实现SimpleTag接口
步骤: a编写标签处理类     b编写标签描述符        c导入并使用
编写标签处理类
        传统方法:实现javax.servlet.jsp.tagext.Tag接口: doStartTag()
        简单方法:实现javax.servlet.jsp.tagext.SimpleTag接口:    doTag()
如果jsp在编译时发现了自定义标签,就会交给doStartTag()或doTag()
编写标签描述符t(Tag)l(library)d(descriptor)

    编写建议:可以仿照 一个其他标签语言(el jstl) 的tld文件

<!--标签库的头文件-->
<taglib 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-jsptaglibrary_2_0.xsd"
    version="2.0">
    
    <description>标签库描述</description>
    <tlib-version>1.0</tlib-version>
    
    
    <display-name>全称</display-name>
    <short-name>简称</short-name>
    <uri>标签库的uri</uri>
    <!--自定义标签的相关信息-->
    <tag>
        <description>标签描述</description>
        <name>标签名</name>
        <tag-class>标签库的实现类</tag-class>
        <body-content>标签体的类型</body-content>
    </tag>
</taglib>

在这里插入图片描述
scriptlet:<% … %>(小脚本) <%! … %> <%= … %>,即scriptless为除了这3个外的元素

导入并使用:
            myTag。tld导入WEB-INF或子目录下(非lib和classes)
            使用:引入具体要使用的tld文件 
                       <%@ taglib uri="xxx", prefix = "x"%>
            uri:每个tld文件的 唯一描述符
            prefix:使用tld标签时的前缀

            具体使用:
                    空标签(没有标签体的标签):<d:foreach></d:foreach>    <d:foreach/>
        
                    带标签体:<d:foreach>xxx</d:foreach>

                    带属性:<d:foreach collection = "${students}">xxx</d:foreach> <d:foreach 属性名= "属性值">xxx</d:foreach>

实际开发步骤:

编写标签处理类
先确保项目有tomcat环境

在这里插入图片描述

Tag接口
        doStartTag:标签处理类得到核心方法(标签体的执行逻辑)
        该方法有以下两个返回值即(01int EVAL_BODY_INCLUDE = 1;  表示该标签体会被执行
        int SKIP_BODY = 0;表示该标签体不会被执行
        doEndTag:标签执行完毕之后的方法,例如可以让标签在执行完毕之后,再执行一次
        int SKIP_PAGE = 5;后面jsp页面内容不被执行
        int EVAL_PAGE = 6;后面jsp页面内容继续执行

在这里插入图片描述

Tag接口中所有方法的执行顺序:
再运行时(jsp会被翻译成servlet(java))当jsp容器(Tomcat,jetty)在将jsp翻译成servlet的时候,
如果遇到jsp中有标签,就会依次执行serPageContext-setParent-doStartTag-doEndTag-release

javax.servlet.jap.tagext.IterationTag接口:(时Tag的子接口)
如果有循环:IterationTag 没有循环:Tag
在这里插入图片描述

doAfterBody:当标签体执行完毕后的操作,通过返回值决定:
            (EVAL_BODY_AGAIN= 2)重复执行
            (SKIP_BODY=0)不再执行

BobyTag接口:如果在标签体被显示之前,进行一些其他的“额外”操作 例如:输出前把小写改为大写

在这里插入图片描述
在这里插入图片描述

int EVAL_BODY_BUFFERED = 2, doStartTag的第三个返回值代表一个缓冲区(Body Content)

BodyContext是abstract 具体使用时需要使用实现类BodyContentImpl(要引入jasper.jar,在配置comcat的comfige中添加)

如果 doStartTag 的返回值 是 EVAL_BODY_BUFFFERED,则服务器会自动将标签体需要显示的内容放入缓冲区中(BodyContent)
因此,如果要更改最终显示结果,只需要从缓冲区中获取原来的数据,进行修改即可
如何获取修改;详见BodyContent中的方法(通过getxxx获取原来的数据,修改后,输出getEncloseingWriter)
在这里插入图片描述

目标:遍历3<xXX>hello<xxx>执行一次,重复两次

编写标签描述符(mytag.tld)

导入并使用
<%@ taglib uri="http://www.yuanqi.com" prefix="c"%>
<c:mytag num="4">hello</c:mytag>

在这里插入图片描述
mytag.tld

<taglib 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-jsptaglibrary_2_0.xsd"
    version="2.0">
	
    <description>这是我的迭代器标签库</description>
    <tlib-version>1.0</tlib-version>

    <short-name>mytaglib</short-name>
    <uri>http://www.yuanqi.com</uri>
	<!--自定义标签的相关信息-->
    <tag>
        <description>这是我的迭代器标签</description>
        <name>mytag</name>
        <tag-class>tag.MyIteration</tag-class>
        <body-content>JSP</body-content>
		<attribute>
			<name>num</name>
			<required>true</required><!--是否必须赋值-->
		</attribute>
    </tag>

    <tag>
        <name>toupper</name>
        <tag-class>tag.ToUpperCast</tag-class>
        <body-content>JSP</body-content>
    </tag>
    <tag>
        <name>s-tag</name>
        <tag-class>tag.SimpleTagIteration</tag-class>
        <body-content>scriptless</body-content>
        <attribute>
            <name>num</name>
            <required>true</required>
        </attribute>
    </tag>
    <tag>
        <name>s-login</name>
        <tag-class>tag.LoginTag</tag-class>
        <body-content>scriptless</body-content>
    </tag>
</taglib>

jsp

<%@ taglib uri="http://www.yuanqi.com" prefix="c"%>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <c:mytag num="4">hello</c:mytag>
  <c:toupper>hello</c:toupper>
  $END$
  <c:s-tag num="3">simple<br/></c:s-tag>

myiteration.java

package tag;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

public class MyIteration extends TagSupport {
    private int num;
    public void setNum(int num){
        this.num = num;
    }
    @Override
    public int doStartTag() throws JspException {
        return EVAL_BODY_INCLUDE;
    }

    @Override
    public int doAfterBody() throws JspException {
        num--;
        return num == 0?SKIP_BODY:EVAL_BODY_AGAIN;
    }
}

touppercast,java

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import java.io.IOException;

public class ToUpperCast extends BodyTagSupport {
    @Override
    public int doStartTag() throws JspException {
        return EVAL_BODY_BUFFERED;
    }//该父类默认返回EVAL_BODY_BUFFERED,故该方法可不重写

    @Override
    public int doEndTag() throws JspException {
        try {
            String content = getBodyContent().getString();

            content = content.toUpperCase();

            bodyContent.getEnclosingWriter().write(content);

        } catch (IOException e) {
            e.printStackTrace();
        }
        return super.doEndTag();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值