第07章:自定义标签

    科技2024-05-22  85

    文章目录

    返回值的各个含义定制标签简介原因 简单标签简介及使用步骤1. 编写简单标签实现类2. 编写TLD文件(标签库描述符文件)3. 在web.xml中配置TLD文件4. 在JSP页面中使用taglib 简单标签的接口简单标签类 标准标签简介及使用标准标签的实现步骤1. 编写标准标签实现类2. 编写TLD文件(同简单标签)3. 在web.xml中配置TLD文件(同简单标签)4. 在JSP页面中使用taglib(同简单标签)课上代码实现1课上代码实现2 Tag接口IterationTag接口IterationTag接口方法IterationTag接口属性 BodyTag接口BodyTag接口方法 TagSupport与BodyTagSupport类TagSupport类BodyTagSupport类 JSP中使用标签文件标签文件的概念标签文件(了解会用就行,不重点)使用标签文件标签文件的伪指令variable伪指令tag伪指令attribute伪指令 标签文件的动作指令jsp:invoke指令jsp:doBody指令 标准标签的代码实现3个标签实现类tld文件web.xml配置文件初始登录界面实验


    返回值的各个含义

    SKIP_BODY,SKIP_PAGE,EVAL_BODY_INCLUDE,EVAL_BODY_AGAIN ---------------------------------------------------------------- SKIP_BODY 隐含0:跳过了开始和结束标签之间的代码。 EVAL_BODY_INCLUDE隐含1:将body的内容输出到存在的输出流中 SKIP_PAGE 隐含5:忽略剩下的页面。 EVAL_PAGE 隐含6:继续执行下面的页 EVAL_BODY_AGAIN 反复执行所处的方法

    定制标签简介

    原因

    JSP表示层中需要编写大量的JSP脚本代码在其他JSP中要重复编写相同的代码,不能做到代码的复用JSP开发者可以创建新的标签来根据实际需求定制对应的方法——定制标签使用自定义标签可以实现页面表示层的代码重用

    简单标签简介及使用

    JSP2.0提供了简单标签来快速实现自定义标签功能 简单标签提供了SimpleTag接口和SimpleTagSupport实现类

    步骤

    1. 编写简单标签实现类
    public class SimpleTagExample extends SimpleTagSupport{ public void doTag() throws JspException,IOException { getJspContext().getOut().print(“simple tag!); } }
    2. 编写TLD文件(标签库描述符文件)

    标签库描述符文件包含的信息可以指导JSP容器解析JSP的定制标签 一个标签库描述符就是一个XML文档,用于通知标签库使用者关于标签库的功能和用法

    <?xml version=1.0” encoding=“utf-8?> <taglib><tag> <name></name> <tag-class></tag-class> <body-content></body-content> <attribute></attribute> </tag> </taglib>

    <taglib> <uri>http://localhost:8080/08-03/math</uri> <tlib-version>1.0</tlib-version> <jsp-version>2.0</jsp-version> <tag> <name>sqrt</name> <tag-class>com.MathTag01</tag-class> <body-content>empty</body-content> <description> Send a math expression to the JSP </description> </tag> </taglib>
    3. 在web.xml中配置TLD文件
    <jsp-config> JSP相关配置 <taglib> 定义在JSP中可使用的库 <taglib-uri>定义TLD文件的URI,JSP页面的tablib命令可以经由此URI获取到TLD文件 <taglib-location> TLD文件所在的位置 ----------------------------------------------------------------------- <jsp-config> <taglib> <taglib-uri>http://localhost:8080/08-03/math</taglib-uri> <taglib-location>/MathTag01.tld</taglib-location> </taglib> </jsp-config>
    4. 在JSP页面中使用taglib
    <%@taglib prefix=“math” uri=..../math"%><math:sqrt />

    简单标签的接口

    SimpleTag接口

    import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport;//注意导包 //简单实现自定义简单标签 public class test1Tag extends SimpleTagSupport { int x = 289; public void doTag() throws JspException, IOException { getJspContext().getOut().print("The squre root of " + x + " is " + Math.sqrt(x) + "."); } }

    SimpleTag生命周期

    初始化,setJspContext() 处理标签内容体,setBody() 调用doTag()方法

    简单标签类

    SimpleTagSupport类

    标准标签简介及使用

    在JSP中可以通过简单标签来实现基本的标签自定义,能够完成简单的标签处理 对于复杂的用户需求标签,JSP提供了标准标签来进行实现 标准标签和简单标签的实现步骤基本一致,只是Java类继承的类不同。具体步骤如下:

    标准标签的实现步骤

    1. 编写标准标签实现类

    编写标准标签实现类的两种方式:

    实现标准接口继承标准标签类 public class RequiredTagimplements Tag { @Override public intdoEndTag() throws JspException{} @Override public intdoStartTag() throws JspException{} @Override public Tag getParent() {} @Override public void setPageContext(PageContextpageContext) {} @Override public void setParent(Tag parentTag) {} }
    2. 编写TLD文件(同简单标签)
    3. 在web.xml中配置TLD文件(同简单标签)
    4. 在JSP页面中使用taglib(同简单标签)

    课上代码实现1
    package mytagprj; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.DynamicAttributes; import javax.servlet.jsp.tagext.SimpleTagSupport; public class test2Tag extends SimpleTagSupport implements DynamicAttributes { double num = 0; String output = ""; public void setNum(double num) { this.num = num; } public void doTag() throws JspException, IOException { getJspContext().getOut().print(output); } @Override//uri。参数属性名,对应的参数属性值 public void setDynamicAttribute(String uri, String localName, Object value)throws JspException { double val = Double.parseDouble((String) value); System.out.println(val); output += "<table border=1>"; if (localName == "min") { output = output + "<tr><td>The minnum of " + num + " and " + val + " </td><td>" + Math.min(num, val) + "</td></tr>"; } else if (localName == "max") { output = output + "<tr><td>The maxnum of " + num + " and " + val + " </td><td>" + Math.max(num, val) + "</td></tr>"; } else if (localName == "pow") { output = output + "<tr><td> " + num + " raised to the " + val + " power </td><td>" + Math.pow(num, val) + "</td></tr>"; } output += "</table>"; } } ------------------------------------------ <tag> <name>test2</name> <tag-class>mytagprj.test2Tag</tag-class> <body-content>empty</body-content> <attribute> <name>num</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <dynamic-attributes>true</dynamic-attributes> </tag> ------------------------------------------------------- <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://localhost:8080/mytagprj/hello" prefix="ww" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <ww:test2 num="5" min="4" max="6" pow="2"/> </body> </html>

    课上代码实现2
    package mytagprj; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.DynamicAttributes; import javax.servlet.jsp.tagext.SimpleTagSupport; public class test3Tag extends SimpleTagSupport implements DynamicAttributes { double num = 0; String output = ""; public void setNum(double num) { this.num = num; } public void doTag() throws JspException, IOException { getJspContext().getOut().print(output); getJspBody().invoke(null); } @Override public void setDynamicAttribute(String uri, String localName, Object value) throws JspException { double val = Double.parseDouble((String) value); System.out.println(val); output += "<table border=1>"; if (localName == "min") { output = output + "<tr><td>The minnum of " + num + " and " + val + " </td><td>" + Math.min(num, val) + "</td></tr>"; } else if (localName == "max") { output = output + "<tr><td>The maxnum of " + num + " and " + val + " </td><td>" + Math.max(num, val) + "</td></tr>"; } else if (localName == "pow") { output = output + "<tr><td> " + num + " raised to the " + val + " power </td><td>" + Math.pow(num, val) + "</td></tr>"; } output += "</table>"; } } ---------------------------------------------- <tag> <name>test3</name> <tag-class>mytagprj.test3Tag</tag-class> <body-content>tagdependent</body-content> <attribute> <name>num</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <dynamic-attributes>true</dynamic-attributes> </tag> ------------------------------------------------ <ww:test3 num="3" min="4" max="5" pow="3"> hello </ww:test3><br>

    ####### 课上代码实现3

    Tag接口

    IterationTag接口

    IterationTag接口方法

    继承自Tag接口具有Tag接口所有的方法 doAfterBody(),执行完标签体内容调用此方法

    IterationTag接口属性

    EVAL_BODY_AGAIN 指明标签内容体循环处理

    BodyTag接口

    BodyTag接口方法

    继承自IterationTag接口 setBodyContent(),将标签内容体实例传入标签 doInitBody()允许标签处理器初始化标签内容体

    TagSupport与BodyTagSupport类

    TagSupport类

    实现了IterationTag接口,提供Tag和IterationTag接口所有方法的默认实现

    BodyTagSupport类

    继承自TagSupport类、实现了BodyTag接口 继承了TagSupport类所有的方法并实现了BodyTag接口,提供setBodyContent()和doInitBody()方法的默认实现。新增getBodyContent()和getPreviousOut()处理缓冲区输出

    JSP中使用标签文件

    标签文件的概念

    除简单标签和标准标签外,JSP2.0规范还提供了一种新的构建标签的形式:标签文件

    JSTL和表达式语言用于减少JSP中Java代码的数量,简单标签用于减少标签处理器实现类中Java代码的数量,使用标签文件可以不依赖Java代码,只要了解JSP语法就可以构建JSP页面中使用的定制标签

    标签文件(了解会用就行,不重点)

    标签文件是由JSP代码组成的,以.tag或.tags为后缀 标签文件可以包含表达式、JSP伪指令、标准标签和自定义标签 JSP元素不能在标签文件中使用

    使用标签文件

    在JSP中使用<%@taglib prefix=“前缀” tagdir=“标签文件地址”%>来导入标签文件所在文件夹 通过前缀加标签文件名来使用一个标签文件,此处文件名不含文件后缀 例子:tag01.jsp <%@taglib prefix=“test” tagdir="/WEB-INF/tags"%>

    标签文件的伪指令

    variable伪指令

    声明JSP变量<%@variable name-given=“x”%>

    tag伪指令

    对整个文件进行设置,类似page指令

    attribute伪指令

    指定属性为静态属性 fragment属性为true允许静态属性中插入JSP代码

    标签文件的动作指令

    标签文件包含了JSP中一系列的动作指令

    jsp:invoke指令

    使attribute伪指令中的fragment生效

    jsp:doBody指令

    用于处理标签内容体

    标准标签的代码实现

    3个标签实现类
    package mytagprj; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.Tag;//注意这个包 public class HelloTag implements Tag {//继承接口 private PageContext pageContext; @Override//结束处理时候调用 public int doEndTag() throws JspException { JspWriter out=pageContext.getOut();//获得输出流对象 try { out.print("hello world");//有可能引发IO异常,所以try catch // out.flush();//因为后面还要用,所以先不关闭 // out.close(); } catch (IOException e) { e.printStackTrace(); } //return 0; //return this.SKIP_PAGE;//跳过此标签后的所有页面;一般不用,除了结束的时候。 return this.EVAL_PAGE; } @Override//被/开始 处理时调用 public int doStartTag() throws JspException { return this.SKIP_BODY;//含义是跳过,不考虑返回值, //本质上和teturn 0是一样的。不信的话可以看源码 //return 0; } @Override//取直接父标签类 public Tag getParent() { return null; } @Override//释放标签资源 public void release() { } @Override public void setPageContext(PageContext arg0) { this.pageContext= arg0; //运行时会自动传过来,接受就好了,值是参数 } @Override public void setParent(Tag arg0) { } /* SKIP_BODY 隐含0:跳过了开始和结束标签之间的代码。 EVAL_BODY_INCLUDE隐含1:将body的内容输出到存在的输出流中 SKIP_PAGE 隐含5:忽略剩下的页面。 EVAL_PAGE 隐含6:继续执行下面的页 EVAL_BODY_AGAIN 反复执行所处的方法 */ } package mytagprj; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyTagSupport; public class IfTag extends BodyTagSupport { private boolean flag;//类当中需要对应的属性 public void setFlag(boolean flag) {//以及需要对应的get与set方法。 this.flag = flag; } @Override public int doStartTag() throws JspException { if(flag) { System.out.println("#####################1"); return this.EVAL_BODY_INCLUDE; }else { System.out.println("#####################2"); return this.SKIP_BODY; } } @Override public int doEndTag() throws JspException { return this.EVAL_PAGE; } } package mytagprj; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyContent; import javax.servlet.jsp.tagext.BodyTagSupport; public class LoopTag extends BodyTagSupport { private BodyContent bodyContent; private int count;//必须有对应的set方法 public void setCount(int count) { this.count = count; } @Override public int doStartTag() throws JspException { return this.EVAL_BODY_BUFFERED;//body体执行 } @Override//结束标签 public int doEndTag() throws JspException { try {//bodycontent(体)得到输出对象,后再打印(标签体的数值) this.bodyContent.getEnclosingWriter().print(this.bodyContent.getString()); } catch (IOException e) { e.printStackTrace(); } return this.EVAL_PAGE; } @Override public void setBodyContent(BodyContent bc) { this.bodyContent = bc; } @Override//核心,控制是否再次执行 public int doAfterBody() throws JspException { if(count>0) {//防止死循环 System.out.println(count); count--; return this.EVAL_BODY_AGAIN;//再执行一遍 }else{ return this.SKIP_BODY;//不执行体 } } }
    tld文件
    <taglib> <uri>http://localhost:8080/mytagprj/hello</uri> <tlib-version>1.0</tlib-version> <jsp-version>2.0</jsp-version> <short-name>f</short-name> <tag> <name>hi</name> <tag-class>mytagprj.HelloTag</tag-class> <body-content>empty</body-content><!-- 无参数 --> </tag> <tag> <name>if</name> <tag-class>mytagprj.IfTag</tag-class> <body-content>JSP</body-content> <attribute> <name>flag</name> <required>true</required> <rtextprvalue>true</rtextprvalue> </attribute> </tag> <tag> <name>loop</name><!-- 名字 --> <tag-class>mytagprj.LoopTag</tag-class><!-- 标签处理类 --> <body-content>JSP</body-content><!-- 有参数 --> <attribute> <name>count</name><!-- 属性名 --> <required>true</required> <rtextprvalue>true</rtextprvalue> </attribute> </tag> </taglib>
    web.xml配置文件
    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>mytagprj</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <jsp-config> <taglib> <!-- 参数与tld有关 --> <taglib-uri>http://localhost:8080/mytagprj/hello</taglib-uri> <taglib-location>/WEB-INF/tags/choose.tld</taglib-location> </taglib> </jsp-config> </web-app>
    初始登录界面
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://localhost:8080/mytagprj/hello" prefix="ww" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <ww:hi/> <br> <ww:if flag="false"> 条件为真了 </ww:if> <ww:loop count="3"> 循环<br> </ww:loop> </body> </html>
    实验

    Processed: 0.019, SQL: 8