自定义标签开发04-简单标签库功能详解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义标签开发04-简单标签库功能详解相关的知识,希望对你有一定的参考价值。


我们回顾一下jsp的Tag自定义标签技术


【自定义标签开发】04-简单标签库功能详解_tag



我们的SimpleTag接口可以实现左边3种接口的功能。


这个接口的默认实现类是SimpleSupport。



接口中的方法有:


doTag()//标签开始和结束都是在这个方法中定义,标签体是setJspBody方法中的JspFragment对象。
可以抛出SkipPageException,就相当于返回了“SKIP_PAGE”,余下的jsp内容就不再执行了。

getParent()//得到父标签对象

setJspBody(JspFragment jspBody)//服务器在调用你的标签前,会将标签作为一个JspFragment对象传送过来。

setJspContext(JspContext pc)//获得JspContext(JspContext继承了PageContext)

setParent()//设置父标签对象


我们下面举一些例子来测试。


1.隐藏页面信息


我们仍然要借助标签来隐藏我们的页面信息:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@taglib uri="/simpleTag" prefix="zyg2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>用简单标签控制是否执行标签体</title>
</head>

<body>

<zyg2:heddin>
Helloworld!
</zyg2:heddin>
</body>

</html>


着手使用SimpleTag来实现这个<zyg2:heddin>标签,首先创建该标签类,继承了SimpleTagSupport:


【自定义标签开发】04-简单标签库功能详解_标签_02



接下来实现doTag()方法:


package org.zyg.web.simpletag;

import java.io.IOException;

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

//控制标签体是否执行
public class HeddinSimpleTag extends SimpleTagSupport

@Override
public void doTag() throws JspException, IOException
JspFragment jf=this.getJspBody();//拿到标签体对象
jf.invoke(this.getJspContext().getOut());//控制标签体执行:输出标签体



我们这里选择了先输出标签体。



然后在WEB-INF下的lib文件夹中创建zygSimple.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>A tag library exercising SimpleTag handlers.</description>
<tlib-version>2.0</tlib-version>
<short-name>zyg2</short-name>
<uri>h/simpleTag</uri><!-- 标签绑定的uri,用于引入 -->


<tag>
<name>heddin</name><!-- 标签名 -->
<tag-class>org.zyg.web.simpletag.HeddinSimpleTag</tag-class>
<body-content>scriptless</body-content><!-- 有无标签体(单标签还是成对标签) -->
</tag>

</taglib>


我们重启Web工程,测试页面:


【自定义标签开发】04-简单标签库功能详解_HTML_03


这是可以看到标签体内容的。


如果不想显示的话,更简单,获得标签体的时候什么也不做就行了:


package org.zyg.web.simpletag;

import java.io.IOException;

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

//控制标签体是否执行
public class HeddinSimpleTag extends SimpleTagSupport

@Override
public void doTag() throws JspException, IOException
JspFragment jf=this.getJspBody();//拿到标签体对象


重启Web项目测试,访问后发现信息不见了:


【自定义标签开发】04-简单标签库功能详解_java_04


简单Tag就是那么简单o(^▽^)o



2.用简单标签迭代标签体


我们让“嘻嘻嘻,好犀利(*^__^*)”执行5遍


<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@taglib uri="/simpleTag" prefix="zyg2" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>用简单标签循环标签体</title>
</head>

<body>

<zyg2:repeat>
嘻嘻嘻,好犀利(*^__^*) <br/>
</zyg2:repeat>
</body>

</html>


然后创建并标签类:


【自定义标签开发】04-简单标签库功能详解_java_05


package org.zyg.web.simpletag;

import java.io.IOException;

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

public class RepeatSimpleTag extends SimpleTagSupport

@Override
public void doTag() throws JspException, IOException
JspFragment jf=this.getJspBody();//拿到标签体对象
for (int i = 0; i < 5; i++)
jf.invoke(this.getJspContext().getOut());



然后在zygSimple.tld中注册这个标签:


<tag>
<name>repeat</name><!-- 标签名 -->
<tag-class>org.zyg.web.simpletag.RepeatSimpleTag</tag-class>
<body-content>scriptless</body-content><!-- 有无标签体(单标签还是成对标签) -->
</tag>


重启Web工程测试:


【自定义标签开发】04-简单标签库功能详解_tag_06


测试成功!



3.用简单标签修改标签体


让标签体文字变大写:


<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@taglib uri="/simpleTag" prefix="zyg2" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>用简单标签循环标签体</title>
</head>

<body>

<zyg2:upper>
abcdefg <br/>
</zyg2:upper>
</body>

</html>


下面来实现<zyg2:upper>标签。


创建并编辑标签处理类:


【自定义标签开发】04-简单标签库功能详解_标签_07


package org.zyg.web.simpletag;

import java.io.IOException;
import java.io.StringWriter;

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

//修改标签体
public class UpperSimpleTag extends SimpleTagSupport

@Override
public void doTag() throws JspException, IOException
JspFragment jf=this.getJspBody();//拿到标签体对象
StringWriter sw=new StringWriter();
jf.invoke(sw);//执行一个带缓冲的Writer

String content=sw.toString();//获得标签体的内容
content = content.toUpperCase();//将内容变为大写

this.getJspContext().getOut().write(content);



然后在zygSimple.tld中注册这个标签:


<tag>
<name>upper</name><!-- 标签名 -->
<tag-class>org.zyg.web.simpletag.UpperSimpleTag</tag-class>
<body-content>scriptless</body-content><!-- 有无标签体(单标签还是成对标签) -->
</tag>


重启Web工程测试:


【自定义标签开发】04-简单标签库功能详解_标签_08


测试成功!



4.用简单标签控制jsp页面的显示


前端标签效果:


<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@taglib uri="/simpleTag" prefix="zyg2" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>用简单标签控制jsp页面的显示</title>
</head>

<zyg2:heddinPage/>

<body>

Hello !

</body>

</html>


下面来实现<zyg2:heddinPage/>标签。


创建并编辑标签处理类:


【自定义标签开发】04-简单标签库功能详解_tag_09


package org.zyg.web.simpletag;

import java.io.IOException;

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

//控制标签余下的jsp不执行
public class HeddinPageSimpleTag extends SimpleTagSupport

@Override
public void doTag() throws JspException, IOException
//只要这个异常抛给jsp,该标签下面的jsp代码就不会执行
throw new SkipPageException();



然后在zygSimple.tld中注册这个标签:


<tag>
<name>heddinPage</name><!-- 标签名 -->
<tag-class>org.zyg.web.simpletag.HeddinPageSimpleTag</tag-class>
<body-content>empty</body-content><!-- 有无标签体(单标签还是成对标签) -->
</tag>


重启Web工程测试:


【自定义标签开发】04-简单标签库功能详解_库_10


可以看到</head>之后的代码没有显示,测试成功!



最后总结一下简单标签的执行流程:


【自定义标签开发】04-简单标签库功能详解_java_11

自定义标签库开发(简单标签开发)

实现Tag接口,BodyTag接口,IterationTag接口的标签开发技术一般称为传统标签开发技术。

实现SimpleTag接口的标签开发技术,一般称为简单标签开发技术。

JSP2.0里新增了SimpleTag。

 

由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的推广, SUN公司为降低标签技术的学习难度,在JSP 2.0中定义了一个更为简单、便于编写和调用的SimpleTag接口来实现标签的功能。实现SimpleTag接口的标签通常称为简单标签。简单标签共定义了5个方法:

setJspContext方法

  用于把JSP页面的pageContext对象传递给标签处理器对象
setParent方法
  用于把父标签处理器对象传递给当前标签处理器对象
getParent方法
  用于获得当前标签的父标签处理器对象
setJspBody方法
  用于把代表标签体的JspFragment对象传递给标签处理器对象
doTag方法
  用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容等。在doTag方法中可以抛出javax.servlet.jsp.SkipPageException异常,用于通知WEB容器不再执行JSP页面中位于结束标记后面的内容,这等效于在传统标签的doEndTag方法中返回Tag.SKIP_PAGE常量的情况。

 

简单标签相关的控制输出逻辑都在doTag里实现

//控制标签体是否执行
public class SimpleTagDemo1 extends SimpleTagSupport {
    @Override
    public void doTag() throws JspException, IOException {
        JspFragment  jf = this.getJspBody();
        //jf.invoke(this.getJspContext().getOut());//invoke是执行标签体,如果不输出标签体,不调用invoke方法即可
    }  
}
<?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>itcast</short-name>
    <uri>/simpletag</uri>
    
    <tag>
        <name>demo1</name>
        <tag-class>cn.itcast.web.simpletag.SimpleTagDemo1</tag-class>
        <body-content>scriptless</body-content>简单标签的标签体不能再写jsp,要写scriptless
    </tag>
</taglib>

 

//迭代标签体
public class SimpleTagDemo2 extends SimpleTagSupport {
    @Override
    public void doTag() throws JspException, IOException {
        JspFragment  jf = this.getJspBody();
        for(int i=0;i<5;i++){
            jf.invoke(null);  //null默认就是jf.invoke(this.getJspContext().getOut());写给浏览器
        }
    }
}

 

//修改标签体
public class SimpleTagDemo3 extends SimpleTagSupport {

    @Override
    public void doTag() throws JspException, IOException {
        JspFragment  jf = this.getJspBody();
        StringWriter sw = new StringWriter();带缓冲的writer
        jf.invoke(sw);写到缓冲里
        
        String content = sw.toString();
        content = content.toUpperCase();
        
        this.getJspContext().getOut().write(content);
    }  
}

 

//控制标签余下的jsp不执行
public class SimpleTagDemo4 extends SimpleTagSupport {
    @Override
    public void doTag() throws JspException, IOException {
        
        throw new SkipPageException();
    }   
}

 

invoke方法

JspFragment.invoke方法是JspFragment最重要的方法,利用这个方法可以控制是否执行和输出标签体的内容、是否迭代执行标签体的内容或对标签体的执行结果进行修改后再输出。例如:
  1. 在标签处理器中如果没有调用JspFragment.invoke方法,其结果就相当于忽略标签体内容;
  2. 在标签处理器中重复调用JspFragment.invoke方法,则标签体内容将会被重复执行;
  3. 若想在标签处理器中修改标签体内容,只需在调用invoke方法时指定一个可取出结果数据的输出流对象(例如StringWriter),让标签体的执行结果输出到该输出流对象中,然后从该输出流对象中取出数据进行修改后再输出到目标设备,即可达到修改标签体的目的。

 

开发带属性的标签:

自定义标签可以定义一个或多个属性,这样,在JSP页面中应用自定义标签时就可以设置这些属性的值,

通过这些属性为标签处理器传递参数信息,从而提高标签的灵活性和复用性。

 

要想让一个自定义标签具有属性,通常需要完成两个任务:

  1. 在标签处理器中编写每个属性对应的setter方法
  2. 在TLD文件中描术标签的属性

 

例子:开发带属性的标签

public class SimpleTagDemo5 extends SimpleTagSupport {

    private int count;
    private Date date;

    public void setCount(int count) {
        this.count = count;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    @Override
    public void doTag() throws JspException, IOException {
        JspFragment  jf = this.getJspBody();
        this.getJspContext().getOut().write(date.toLocaleString() + "<br/>");
        for(int i=0;i<count;i++){
            jf.invoke(null);
        }
    }
}

 

simpletag.tld

<tag>
        <name>demo5</name>
        <tag-class>cn.itcast.web.simpletag.SimpleTagDemo5</tag-class>
        <body-content>scriptless</body-content>
        
        <attribute>
            <name>count</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>运行时表达式的值,如果为true,则可以运行时赋值,如果是false,值只能写个固定值
        </attribute>
        
        <attribute>
            <name>date</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/simpletag" prefix="sitcast" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>开发带属性的标签</title>
  </head>
  
  <body>
     <sitcast:demo5 count="3" date="<%=new Date() %>">
         aaaaaa
     </sitcast:demo5>
  </body>
</html>

 

以上是关于自定义标签开发04-简单标签库功能详解的主要内容,如果未能解决你的问题,请参考以下文章

自定义标签库开发(简单标签开发)

JSP2 的自定义标签

杂项-Java:自定义标签

开发属于我们自己的标签库!

JSP第六篇自定义标签之传统标签

jsp的标签库和自定义标签