【JavaWeb】Jsp的自定义标签
一、概述
JSP技术提供了一种封装动态类型的机制—自定义标签,它扩展了JSP语言。自定义标签通常发布在标签库中,标签库定义了一个自定义标签集并包含实现标签的对象。页面中的某些功能可以通过自定义标签来实现,包括对隐含对象的操作,处理表单,访问数据库集等其它企业级服务,如e-mail,目录服务,处理流控制等等。
特点:
- 可以通过调用页面传递的属性进行自定义;
- 可以访问对于JSP页面可能的所有对象;
- 可以修改由调用页面产生的响应;
- 可以相互间通信;
- 可以嵌套使用实现复杂的交互。
具体定义:
自定义标签是用户定义的JSP语言元素,每一个标签对应一个实现了特定接口的Java处理类,封装了Java代码编写的预定义行为。在运行时,标签被替换成相应的预定义Java代码,并用来处理标签逻辑。
换句话说,当JSP页面包含一个自定义标签,那么在运行时,标签时会被转化为servlet运行,通过Web容器来调用对应的标签逻辑。自定义标签使用的目的在于将业务和表示逻辑分离,提高代码的可重用性和可移植性。
二、自定义标签的构建步骤
(一)简单的自定义标签
例如:<example: hello /> //“example” 是标签前缀,可自定义;“hello” 是对应的标签库tld文件内自定义的名称
1. 创建被实现了特定接口的Java处理类
下面有普通标签支持接口和简单标签支持接口两种继承方式,二者选其一,接下来主要以继承简单标签支持接口示例。
(1)普通标签支持接口
package cn.edu.lingnan.tag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import java.io.IOException;
public class function extends TagSupport {
@Override
public int doStartTag() throws JspException {
try {
pageContext.getOut().println("Hello tag!");
} catch (IOException e) {
e.printStackTrace();
}
return SKIP_BODY; //跳过标签体,因为根本没有标签体
}
@Override
public int doEndTag() throws JspException {
return EVAL_PAGE; //不跳过页面。继续执行标签之后的内容
}
}
(2)简单标签支持接口
package cn.edu.lingnan.tag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;
public class function extends SimpleTagSupport {
@Override
public void doTag() throws JspException, IOException {
JspWriter out = getJspContext().getOut();
out.println("Hello Tag!");
}
}
2. 建立标签库文件mytag.tld(以IDEA为例)
(1)在如下路径下建立文件夹tld
(2)在tld文件夹下建立tld为后缀的xml文件
(3)新建后,tld文件内容如下
(4)在标签库tld文件内添加标签内容配置
另,如果是使用eclipse工具,则还要再web.xml中添加如下配置内容
3. 在jsp文件中使用自定义标签
三、访问标签体内容
标签体内容即为标签中间所可以包含的内容,有如下几种
类别 | 详解 |
---|---|
empty | 表示标签中没有body |
JSP | 表示标签的body中可以加入JSP程序代码 |
scriptless | 接受文本、EL和JSP动作,但不能含有脚本元素 |
tagdependent | 表示标签中的内容由标签自己去处理 |
当标签体如下时,如何访问标签体内容呢?
<ex:Hello>
This is message body
</ex:Hello>
(一)编写标签处理类
package com.runoob;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;
public class HelloTag extends SimpleTagSupport {
StringWriter stringWriter = new StringWriter();
public void doTag()
throws JspException, IOException
{
getJspBody().invoke(stringWriter);
getJspContext().getOut().println(stringWriter.toString());
}
}
(二)在tld文件编写自定义标签的配置
<?xml version="1.0" encoding="ISO-8859-1"?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
<tlib-version>1.0</tlib-version>
<short-name>mytags</short-name>
<uri>http://lingnan.edu.cn</uri>
<!-- Invoke 'Generate' action to add tags or functions -->
<tag>
<description>????</description> <!-- 自定义的标签描述 -->
<name>Hello</name> <!-- 自定义的标签名称 -->
<tag-class>cn.edu.lingnan.tag.HelloTag</tag-class> <!-- 映射到标签的Java实现类 -->
<body-content>scriptless</body-content> <!-- 标签体内容 -->
</tag>
</taglib>
(三)在jsp文件中使用自定义标签
<%@ taglib prefix="ex" uri="http://lingnan.edu.cn"%>
<html>
<head>
<title>A sample custom tag</title>
</head>
<body>
<ex:Hello>
This is message body
</ex:Hello>
</body>
</html>
四、定义和使用自定义标签的属性
(一)在jsp中的自定义标签
<%@ taglib prefix="ex" uri="http://lingnan.edu.cn"%>
<html>
<head>
<title>A sample custom tag</title>
</head>
<body>
<ex:Hello message="This is message body">
I have a message
</ex:Hello>
</body>
</html>
(二)带属性的自定义标签在tld文件中的配置
<?xml version="1.0" encoding="ISO-8859-1"?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
<tlib-version>1.0</tlib-version>
<short-name>mytags</short-name>
<uri>http://lingnan.edu.cn</uri>
<!-- Invoke 'Generate' action to add tags or functions -->
<tag>
<description>????</description> <!-- 自定义的标签描述 -->
<name>Hello</name> <!-- 自定义的标签名称 -->
<tag-class>cn.edu.lingnan.tag.HelloTag</tag-class> <!-- 映射到标签的Java实现类 -->
<body-content>empty</body-content> <!-- 标签体内容 -->
<!-- 属性的配置,若有多个属性,该attribute配置标签可复用 -->
<attribute>
<name>message</name>
<required>true</required>
<type>String</type>
<fragment>false</fragment>
</attribute>
</tag>
</taglib>
自定义标签的属性有如下基本配置:
属性配置 | 描述 |
---|---|
name | 定义属性的名称。每个标签的是属性名称必须是唯一的。 |
required | 指定属性是否是必须的或者可选的,如果设置为false为可选。 |
rtexprvalue | 声明在运行表达式时,标签属性是否有效。 |
type | 定义该属性的Java类类型 。默认指定为 String |
fragment | 如果声明了该属性,属性值将被视为一个 JspFragment。 |
(三)在标签处理类中接收属性值
可以在自定义标准中设置各种属性,要接收属性,值自定义标签类必须实现setter方法, JavaBean 中的setter方法如下所示:
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;
public class HelloTag extends SimpleTagSupport {
private String message;
private StringWriter stringWriter = new StringWriter();
public void setMessage(String msg) {
this.message = msg;
}
public void doTag()
throws JspException, IOException
{
if (message != null) {
/* 从属性中使用消息 */
JspWriter out = getJspContext().getOut();
out.println( message );
}
else {
/* 从内容体中使用消息 */
getJspBody().invoke(stringWriter);
getJspContext().getOut().println(stringWriter.toString());
}
}
}