1、一个普通的JSP标签如下图所示:
2、简单标签
1)定义:
无正文无属性或无正文有属性的JSP标签
2)简单标签和正文标签的区别:
3)一个无正文无属性标签的示例:
<mytag:helloworld /> 或 <mytag:helloworld></mytag:helloworld>
4)制作无正文无属性标签
首先要在对应的 java 文件中实现标签处理类
①扩展javax.servlet.jsp.tagext.TagSupport
②重写public int doEndTag()方法(需要抛出JspException异常)
5)无正文无属性标签使用示例
index.jsp(在web/目录下)
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="myfn" uri="/WEB-INF/tld/myfn.tld" %> <html> <head> <title>JSTL-自定义无正文标签</title> </head> <body> <myfn:HelloWorld/> </body> </html>
myfn.tld(在web/WEB-INF/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>Myfu</short-name> <!-- 直接输出Hello World!--> <tag> <name>HelloWorld</name> <tag-class>cn.qi.Myfu.MyFunctions</tag-class> <!-- 标签正文为空时为empty--> <body-content>empty</body-content> </tag> </taglib>
MyFunctions.java(在src/cn.qi.Myfu/目录下)
package cn.qi.Myfu; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.TagSupport; import java.io.IOException; public class MyFunctions extends TagSupport { @Override public int doEndTag() throws JspException { try { pageContext.getOut().print("hello"); } catch (IOException e) { // 捕获异常并输出在控制台中 throw new JspException(e.getMessage()); } return super.doEndTag(); } }
6)制作无正文有属性标签
①扩展javax.servlet.jsp.tagext.TagSupport
②重写public int doEndTag()并抛出JspException异常
③增加类属性 text 及其 Getter 和 Setter 方法
7)无正文有属性标签使用示例
index.jsp(在web/目录下)
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="myfn" uri="/WEB-INF/tld/myfn.tld" %> <html> <head> <title>JSTL-自定义无正文标签</title> </head> <body> <myfn:printString text="hehe"/> </body> </html>
myfn.tld(在web/WEB-INF/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>Myfu</short-name> <tag> <name>printString</name> <tag-class>cn.qi.Myfu.MyFunctions</tag-class> <body-content>empty</body-content> <attribute> <name>text</name> <required>true</required> <!-- 从页面里进行传递--> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
MyFunctions.java(在src/cn.qi.Myfu/目录下)
package cn.qi.Myfu; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.TagSupport; import java.io.IOException; public class MyFunctions extends TagSupport { private String text; public String getText() { return text; } public void setText(String text) { this.text = text; } @Override public int doEndTag() throws JspException { try { pageContext.getOut().print(text); } catch (IOException e) { // 捕获异常并输出在控制台中 throw new JspException(e.getMessage()); } return super.doEndTag(); } }
3、正文标签
1)定义
正文标签可以对标签的正文进行读取和处理
2)使用示例
定义一个Repeat标签,功能是将正文内容全部转换为大写字母并重复输出count次
①首先在项目目录的src文件夹下创建一个包,包里包含一个java类文件Repeat,例如:
②正文标签处理类需要扩展javax.servlet.jsp.tagext.BodyTagSupport类并重载doAfterBody()方法,例如:
package cn.qi.Repeat; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyTagSupport; public class Repeat extends BodyTagSupport { public int doAfterBody() throws JspException {} }
③当标签内的正文被系统处理完之后,会调用doAfterBody()方法。如果方法返回EVAL_BODY_AGAIN则系统会循环再处理正文一次,直到该方法返回SKIP_BODY为止。
正文标签状态图:
④在标签处理类中定义属性并填写doAfterBody()方法
⑤在web/WEB-INF(或web/WEB-INF/tld)目录下新建一个tld(标签库描述)文件,标签库描述文件的名称为标签库的前缀,例如在上述目录下新建一个myTag.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>myTag</short-name> <tag> <name>Repeat</name> <tag-class>cn.qi.Repeat.Repeat</tag-class> <body-content>JSP</body-content> <attribute> <name>count</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
<tag>标签内的属性值描述:
name:标签名
tag-class:标签处理类所在的位置
body-content:标签内容的处理方式,其标签体内可以有四种值,分别是:
- tagdependent:标签体内容直接被写入BodyContent,不被JSP容器解释。
- JSP:接受所有JSP语法,如定制的或内部的tag、scripts、静态HTML、脚本元素、JSP指令和动作。
- empty:空标记,即起始标记和结束标记之间没有内容。
- scriptless:接受文本、EL和JSP动作。
<attribute>标签内是自定义标签的属性
例如上面的tld文件中只有一个属性count,对应着Repeat类中的私有属性count。
<name>标签定义属性名称,<required>标签定义该属性是否必须在标签内使用,<rtexprvalue>标签定义该属性是否能使用表达式。
⑥在JSP页面中使用taglib指令指定自定义标签的前缀和描述文件的位置,例如:
<%@ taglib prefix="myTag" uri="/WEB-INF/tld/myTag.tld" %>
3)完整代码:
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="myTag" uri="/WEB-INF/tld/myTag.tld" %> <html> <head> <title>$Title$</title> </head> <body> <myTag:Repeat count="3"> This is a test! </myTag:Repeat> </body> </html>
myTag.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>myTag</short-name> <tag> <name>Repeat</name> <tag-class>cn.qi.Repeat.Repeat</tag-class> <body-content>JSP</body-content> <attribute> <name>count</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
Repeat.java
package cn.qi.Repeat; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.BodyContent; import javax.servlet.jsp.tagext.BodyTagSupport; import java.io.IOException; public class Repeat extends BodyTagSupport { private int count; public int getCount() { return count; } public void setCount(int count) { this.count = count; } public int doAfterBody() throws JspException { try { if (count > 0) { BodyContent body = getBodyContent(); JspWriter writer = body.getEnclosingWriter(); // 从正文中获取字符串 writer.print(body.getString().toUpperCase()); body.clearBody(); count--; return EVAL_BODY_AGAIN; } else { return SKIP_BODY; } } catch (IOException e) { throw new JspException(e.getMessage()); } } }