1.定制标签的实现类称为标签处理器,简单标签处理器指实现SimpleTag接口的类,如下图的SimpleTagSupport类,该类为SimpleTag接口的默认实现类。

  注:不要直接实现SimpleTag接口,应该继承SimpleTagSupport类,可以直接使用该类已经实现的方法,若该类方法不能满足业务需求,可重写相应方法。

.

2.SimpleTag接口定义了5个方法:

  • setJspContext方法
  • setParent和getParent方法
  • setJspBody方法
  • doTag方法(非常重要),简单标签使用这个方法就可以完成所有的业务逻辑

  2.1 setJspContext方法:

    用于把JSP页面的pageContext对象传递给标签处理器对象,若重写该方法,必须把PageContext赋于成员变量jspContext

  2.2 setParent方法:

    用于把父标签处理器对象传递给当前标签处理器对象

  2.3 getParent方法:

    用于获得当前标签的父标签处理器对象

  2.4 setJspBody方法:

    用于把代表标签体的JspFragment对象传递给标签处理器对象,若重写了该方法,必须赋于成员变量jspFragment

  2.5 doTag方法:
    用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容等。在doTag方法中可以抛出javax.servlet.jsp.SkipPageException异常,用于通知WEB容器不再执行JSP页面中位于结束标记后面的内容,这等效于在传统标签的doEndTag方法中返回Tag.SKIP_PAGE常量的情况。

3. SimpleTag接口方法的执行顺序

  当web容器开始执行标签时,会调用如下方法完成标签的初始化:

  1. WEB容器调用标签处理器对象的setJspContext方法,将代表JSP页面的pageContext对象传递给标签处理器对象。
  2. WEB容器调用标签处理器对象的setParent方法,将父标签处理器对象传递给这个标签处理器对象。注意,只有在标签存在父标签的情况下,WEB容器才会调用这个方法。
  3. 如果调用标签时设置了属性,容器将调用每个属性对应的setter方法把属性值传递给标签处理器对象。如果标签的属性值是EL表达式或脚本表达式,则WEB容器首先计算表达式的值,然后把值传递给标签处理器对象。
  4. 如果简单标签有标签体,WEB容器将调用setJspBody方法把代表标签体的JspFragment对象传递进来。
  5. 执行标签时WEB容器调用标签处理器的doTag()方法,开发人员在方法体内通过操作JspFragment对象,就可以实现是否执行、迭代、修改标签体的目的。

4.JspFragment类介绍

  4.1全称javax.servlet.jsp.tagext.JspFragment,WEB容器在处理简单标签的标签体时,会把标签体内容用一个JspFragment对象表示,并调用标签处理器对象的setJspBody方法把JspFragment对象传递给标签处理器对象。

  4.2 JspFragment类中只定义了两个方法:

   4.2.1 getJspContext方法:public abstract void invoke(java.io.Writer out) ;//用于返回代表调用页面的JspContext对象。

   4.2.2 invoke方法:public abstract void invoke(java.io.Writer out);

/*用于执行JspFragment对象所代表的JSP代码片段,参数out用于指定将JspFragment对象的执行结果写入到哪个输出流对象中,如果 传递给参数out的值为null,则将执行结果写入到JspContext.getOut()方法返回的输出流对象中。(简而言之,可以理解为写给浏览器);

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

5. 标签属性描述:

  

6.开发简单标签实现页面逻辑

  6.1 标签处理器类:

 package com.webtest.tag;

 import java.io.IOException;
import java.io.StringWriter; import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport; public class TestTag extends SimpleTagSupport {
//private JspContext jspContext;
//private JspFragment jspFragment;
private int count;//定义标签属性 public void setCount(int count){
this.count=count;
}
@Override
public void doTag() throws JspException, IOException {
// TODO Auto-generated method stub //获取PageContext对象,若重写了setJspContext方法,必须把PageContext赋于成员变量jspContext
PageContext pageContext = (PageContext) this.getJspContext(); pageContext.getOut().print("这里是10086<br>"); //得到代表jsp标签体的JspFragment,若这个类重写了setJspBody方法,必须赋于成员变量jspFragment,所以不需要调用getJspBody方法
JspFragment jspFragment=this.getJspBody(); //将标签体的内容输出到浏览器
jspFragment.invoke(null);
pageContext.getOut().print("<br>"); /*
* 或者把标签条输入缓冲流中,然后对数据进行修改
*/
StringWriter sw=new StringWriter();
jspFragment.invoke(sw);
String str=sw.getBuffer().toString();
str="####"+str+"####"; pageContext.getOut().print(str+"<br>"); //使用标签属性
for(int i=0;i<count;i++){
jspFragment.invoke(null);
}
//得到jsp页面的的PageContext对象
//PageContext pageContext = (PageContext) jspFragment.getJspContext();
//调用JspWriter将标签体的内容输出到浏览器
//jspFragment.invoke(pageContext.getOut());
System.out.println("doTag方法"); } /* public JspTag getParent() {
// TODO Auto-generated method stub
System.out.println("getParent方法");
return null;
}*/ /**
* 当重写setJspBody方法时,需要把传如的JspFragment对象赋值给一个类变量,以供使用
*/
/*
public void setJspBody(JspFragment jspBody) {
// TODO Auto-generated method stub
jspFragment=jspBody;
System.out.println("setJspBody方法");
} public void setJspContext(JspContext pc) {
// TODO Auto-generated method stub
System.out.println("setJspContext方法");
jspContext=pc;
} public void setParent(JspTag parent) {
// TODO Auto-generated method stub
System.out.println("setParent方法");
}*/ }

  6.2 标签描述文件,是xml文件,以tld为后缀名,一般放在WEB-INF目录下,也可以置于其他目录:

 <?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>自定义标签库</description>
<!-- 标签库的 版本号 -->
<tlib-version>1.0</tlib-version>
<short-name>GaclSimpleTagLibrary</short-name>
<!--
为自定义标签库设置uri,以 / 开头,/之后的内容随意,如这里的/simpletag,但应该把其设置成与文件名相同,以便知道引用哪个标签库
在jsp页面使用自定义标签时,需要先引入标签库,其通过uri找到标签库,
jsp页面引入标签库:<%@taglib uri="/simpletag" prefix="gacl" %>
其中的prefix属性用于使用自定义标签时的前缀,如同EL中的c,如:<gacl:tagtest/>
-->
<uri>/mytags</uri>
<!-- 一个taglib(标签库)可以包含多个自定义标签,每个自定义标签使用一个tag来描述 -->
<tag>
<!-- 描述 -->
<description>SimpleTag(简单标签)tagtest</description>
<!-- 标签名,为标签处理器类配一个标签名,使其在jsp页面可以通过标签名找到 -->
<name>tagtest</name>
<!-- 标签对应的标签处理器类 -->
<tag-class>com.webtest.tag.TestTag</tag-class>
<!--
tld文件中有四种标签体类型 :empty JSP scriptless tagdepentend
在简单标签(SampleTag)中标签体body-content的值只允许是empty和scriptless,不允许设置成JSP,如果设置成JSP就会出现异常
在传统标签中标签体body-content的值只允许是empty和JSP
如果标签体body-content的值设置成tagdepentend,那么就表示标签体里面的内容是给标签处理器类使用的,
例如:开发一个查询用户的sql标签,此时标签体重的SQL语句就是给SQL标签的标签处理器来使用的
<gacl:sql>SELECT * FROM USER</gacl:sql>
在这种情况下,sql标签的<body-content>就要设置成tagdepentend,tagdepentend用得比较少,了解一下即可
-->
<body-content>scriptless</body-content>
<!-- 标签属性描述 -->
<attribute>
<description>描述标签的count属性</description>
<name>count</name>
<!-- 用于表示此属性是否必须设置,默认为false,即可以不设置该属性的值 -->
<required>true</required>
<!-- rtexprvalue用于指示标签属性值是否可以是一个表达式,一般设置为true,表示可以是表达式 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>

6.3  jsp文件:

 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

 <%--导入自定义标签库 --%>
<%@taglib uri="/mytags" prefix="gacl" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head> <body>
<gacl:tagtest count="5">我是自定义标签<p></gacl:tagtest> </body>
</html>

JSP简单标签标签库开发的更多相关文章

  1. javaweb学习总结(二十六)——jsp简单标签标签库开发(二)

    一.JspFragment类介绍 javax.servlet.jsp.tagext.JspFragment类是在JSP2.0中定义的,它的实例对象代表JSP页面中的一段符合JSP语法规范的JSP片段, ...

  2. javaweb(二十六)——jsp简单标签标签库开发(二)

    一.JspFragment类介绍 javax.servlet.jsp.tagext.JspFragment类是在JSP2.0中定义的,它的实例对象代表JSP页面中的一段符合JSP语法规范的JSP片段, ...

  3. jsp简单标签开发(一)

    孤傲苍狼 @Override22 public void doTag() throws JspException, IOException {23 //得到代表jsp标签体的JspFragment24 ...

  4. javaweb学习总结(二十七)——jsp简单标签开发案例和打包

    一.开发标签库 1.1.开发防盗链标签 1.编写标签处理器类:RefererTag.java 1 package me.gacl.web.simpletag; 2 3 import java.io.I ...

  5. javaweb学习总结(二十五)——jsp简单标签开发(一)

    一.简单标签(SimpleTag) 由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的推广, SUN公司为降低标签技术的学习难度,在JSP 2.0中定义了一个更为简单.便于编 ...

  6. jsp 简单标签开发

    实现simpleTag接口的标签通常称为是简单标签,简单标签一共定义了5个方法 setJspContext方法 setParent方法 getParent方法 setJspBody方法 doTag方法 ...

  7. JSP简单标签开发

    一.继承自SimpleTag接口的自定义标签实现类称为简单标签,接口中5个方法 1.setJspContext方法 用于把JSP页面的PageContext对象传递给标签处理器对象 2.setPare ...

  8. JSP内置标签 JSP中JavaBean标签 JSP开发模式 EL和JSTL快速入门

    2 JSP内置标签(美化+业务逻辑)   1)为了取代<%%>脚本形式,使用JSP标签/JSP动作,目的:与JSP页面的美化,即JSP面页都是由标签组成,不再有其它的内容   2)JSP内 ...

  9. 学会怎样使用Jsp 内置标签、jstl标签库及自定义标签

    学习jsp不得不学习jsp标签,一般来说,对于一个jsp开发者,可以理解为jsp页面中出现的java代码越少,对jsp的掌握就越好,而替换掉java代码的重要方式就是使用jsp标签.  jsp标签的分 ...

随机推荐

  1. LINQ 查询集合总的重复项

                      select new FMDS_FarmPlotNewInfo                   {                        FarmPlo ...

  2. html5权威指南:标记文字、组织内容、文档分节

    HTML5新增及删除标签:http://www.cnblogs.com/starof/archive/2015/06/23/4581850.html 第八章:标记文字                 ...

  3. PAT 团体程序设计天梯赛-练习集 L1-020. 帅到没朋友

    原题  https://www.patest.cn/contests/gplt/L1-020 当芸芸众生忙着在朋友圈中发照片的时候,总有一些人因为太帅而没有朋友.本题就要求你找出那些帅到没有朋友的人. ...

  4. JavaScript的BOM(浏览器对象)基础语法总结

    1.window对象是BOM的核心,window对象指当前的浏览器窗口. window对象方法: 2.history对象记录了用户曾经浏览过的页面(URL),并可以实现浏览器前进与后退相似导航的功能. ...

  5. ckeditor上传图片的注意点

    1.要在 ckeditor的  config.js 文件中加上 CKEDITOR.editorConfig = function( config ) { config.filebrowserImage ...

  6. BitSort

    这个题为<编程珠玑>中提到的算法,解题思路和桶排序/基数排序一样,适用于大量没有重复的数据. 结题思路: 1.遍历整个数据文件,每提取一个数据,在BitMap中对应的位置赋1 2.遍历Bi ...

  7. Java IO 节点流 ByteArrayInput/OutputStream

    Java IO 节点流 ByteArrayInput/OutputStream @author ixenos ByteArrayInputStream 包含一个内部缓冲区(字节数组byte[]),该缓 ...

  8. Excel教程(6) - 外部函数

    EUROCONVERT 用途:将数字转换为欧元形式,将数字由欧元形式转换为 欧盟成员国货币形式,或利用欧元作为中间货币将数字由某一 欧盟成员国货币转化为另一欧盟成员国货币的形式(三角转换 关系). 语 ...

  9. C# 二维数组和集合

    本次课我主要学习了二维数组和集合的部分内容. 在二维数组的部分中,我主要学习了二维数组的定义方法:int [,] array=new int [4,2];做了一个小练习:用二维数组打印自己的姓氏. s ...

  10. ASP.NET之.NET FrameWork框架

    .NET FrameWork框架 是一套应用程序开发框架,主要目的提供一个开发模型. 主要的两个组件: 公共语言运行时(Common Language Runtime)(CLR): 提供内存管理.线 ...