Servlet和JSP之自定义标签学习

时间:2023-03-09 03:53:13
Servlet和JSP之自定义标签学习

    此文章会讲述简单标签处理器,因为经典自定义标签处理器没有简单标签处理器方便使用,故在此不进行描述。

参考:慕课网的《JSP自定义标签》视频;

    《Servlet、JSP和Spring MVC初学指南》的第六章;

    IBM的《利用 JSP 2 提供的 SimpleTagSupport 开发自定义标签》;

    菜鸟教程的JSP自定义标签文章。  


自定义标签  

  自定义标签

自定义标签就是将方法封装到自定义标签处理类中,然后使用方法与JSTL标签来达到,解决JSP中JavaBean的展现与业务实现分离问题。自定义标签提供了在JavaBean中所不能实现的便利,其中就包括,自定义标签允许访问JSP中隐藏的对象及它们的属性。

自定义标签的实现,叫做标签处理器,而简单标签处理器是指实现SimpleTag接口(或继承SimpleTagSupport类)实现的标签处理器,经典标签处理器是指实现BodyTag接口(或继承BodyTagSupport类)等实现的标签处理器。

  自定义标签的继承结构

    JSP<----Tag <----IterationTag<----TagSupport<----BodyTagSupport<-----BodyTag

    JSP<----SimpleTag<-----SimpleSupportTag

简单标签处理器

简单标签处理器有简单的生命周期,SimpleTag接口中用于标签触发的方法只有一个------doTag,并且该方法只会执行一次。业务逻辑、遍历及页面内容操作都在这里实现。简单标签处理器中的页面内容都在JspFragment类的实例中体现。

简单标签的生命周期如下:

1)       JSP容器通过简单标签处理器的无参数构造器创建它的实例,因此,简单标签处理器必须有无参数构造器(一般不用自己写, 用系统默认的就可以了)。

2)       JSP容器通过setJspContext的方法,传入JspContext对象:该对象中最重要的方法是getOut(),它能返回JspWriter,通过JspWriter就可以把响应返回前端了。

3)       如果自定义标签被另一个自定义标签所嵌套,JSP容器就会调用setParent的方法。

4)       JSP容器调用该标签中所定义的每个属性的Set方法。

5)       如果需要处理页面内容,JSP容器还会调用SimpleTag接口的setJspBody方法,把使用JspFragment封装的页面内容传过来。当然,如果没有页面内容,那么JSP容器不会调用该方法。

  接下来是SimpleTag接口的详解

方法

说明

doTag()方法

是核心方法,用于编写标签处理逻辑。

setParent(JspTag)方法

将父标签处理器对象传递给标签处理器。

getParent()方法

获取当前标签的父标签对象。

setJspContext(JspContext)方法

将JSP页面的pageContext对象传递给标签处理器对象。

setJspBody(JspFragment)方法

将代表当前标签体的JspFragment对象传递给标签处理器对象。(JspFragment中的invoke(Writer)方法用于执行JspFragment对象所代表的代码段)

  

  是不是看着上面的一大串文字,有点懵?没事儿,下面就是关于实现SimpleTagSupport类(跟实现SimpleTag接口的功用类似)的例子。

  首先需要准备一个SimpleTag的.tld文件,用于注册自定义标签,这个文件是在apache-tomcat文件里面,一般地址是在E:\apache-tomcat-6.0.39\webapps\examples\WEB-INF\jsp里面,名称是jsp2-example-taglib.tld

  用一个显示当前时间的jsp页面来做为第一个例子:

  自定义标签的创建步骤

1)       创建标签处理类

package com.ny.tag2;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class DisplayInfo extends SimpleTagSupport{

    @Override
    public void doTag() throws JspException, IOException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
        String dateStr = simpleDateFormat.format(new Date());
        JspWriter jspWriter = getJspContext().getOut();
        jspWriter.write(dateStr);
    }
}

2)       创建标签库文件

  在WEB-INF目录下创建一个.tld文件(如nyTag.tld),然后打开jsp2-example-taglib.tld文件,里面有我们需要的taglib配置,打开这个文件之后找到下面的代码段,复制到nyTag.tld中。

  如果tid文件位于WEB-INF文件下面,Tomcat会自动加载tld文件中的标签库。如果位于其他位置,其实也可以在web.xml中配置。

<?xml version="1.0" encoding="UTF-8" ?>
<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>A tag library exercising SimpleTag handlers.        </description>
    <tlib-version>1.0</tlib-version>
    <short-name>SimpleTagLibrary</short-name>
    <uri>/SimpleTagLibrary</uri>
</taglib>

 

3)       在标签库文件中注册标签

<?xml version="1.0" encoding="UTF-8" ?>
<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>A tag library exercising SimpleTag handlers.        </description>
    <tlib-version>1.0</tlib-version>
    <short-name>ny</short-name>
    <uri>/ny-tag</uri>
    <tag>
        <name>dateInfo</name>
        <tag-class>com.ny.tag2.DisplayInfo</tag-class>
        <body-content>empty</body-content>
    </tag>
</taglib>

① <short-name>:指明推荐使用的prefix(这个属性会在jsp页面中引入标签的时候出现)。

② <uri>:指明引用这个标签库时使用的uri(注意哦是uri不是url)。

③ <tag>:指明要定义标签的信息。

其中,tag可以设置的属性如下:

属性

说明

name

定义属性的名称,每个标签的属性名称必须是唯一的。

tag-class

指定映射的Java类。

required

指定属性是否是必须的或者可选的,如果是必须的就设置为true。

rtexprvalue

声明在运行表达式时,标签属性是否有效,有效则为true。

type

定义该属性的Java类类型,默认指定为String。

decription

描述信息

fragment

如果声明了该属性,属性值将被视为一个JspFragment。

bodycontent

指明标签体的限定,可以有以下几种取值(想了解更多可以在”参考”中查找到):a) empty:指定该标签只能作用空标签使用;b) scriptless:指定该标签的标签体可以是静态HTML元素、表达式语言,但不允许出现JSP脚本。

4)       在页面中引入标签库

<%@ taglib prefix="ny" uri="/ny-tag"%>

5)       在页面中使用标签

<body>
    <imooc:dateInfo/>
</body>

  所以JSP页面中的代码就是:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="imooc" uri="/imooc-tag2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <imooc:dateInfo/>
</body>
</html>

  

  是不是感觉还挺简单的呢? 其实自定义标签的用法不止这些哦,加油吧!