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. Cookie的简单使用

    一,新建一个空网站,添加一个Default.aspx <%@ Page Language="C#" AutoEventWireup="true" Code ...

  2. java 用双向链表实现SJBLinkedList

    public class SJBLinkedList{ private Node first; private Node last; private int size; public int size ...

  3. GOPS 2016全球运维大会 • 北京站概况

    GOPS 2016全球运维大会上海站已圆满落幕,错过上海站的朋友或许会感到一些遗憾,但是不用担心,在12月16日,GOPS 2016全球运维大会 • 北京站将隆重召开,错过上海在的朋友可以赶上北京站哦 ...

  4. 《JS权威指南学习总结--8.8.2高阶函数》

    内容要点: 所谓高阶函数(higher-order function)就是操作函数的函数,它接收一个或多个函数作为参数,并返回一个新函数. 例1: //这个高阶函数返回一个新的函数,这个新函数将它的实 ...

  5. C#微型网页查看工具

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  6. webpack - tree shaking

    Tree-shaking with webpack 2 and Babel 6 babel-webpack-tree-shaking Ben Levwis

  7. poj 3524 Charm Bracelet(01背包)

    Description Bessie has gone to the mall's jewelry store and spies a charm bracelet. Of course, she'd ...

  8. Gentoo:Xorg:Failed to load module "……" 问题

    错误描述: 安装完xorg-server后,startx启动桌面环境,出现缺少模块错误. Xorg:Failed to load module "--" 查看log: cat /v ...

  9. CEdit实现文本换行

    CEdit控件若要在字符串中插入换行字符("\r\n")实现换行效果,必须指定两个风格 ES_MULTILINE和ES_WANTRETURN. 1: DWORD dwStyle = ...

  10. Oracle数据库插入数据出错:ORA-06550

    wpf应用调用oracle的存储过程,出错“ORA-06550:参数个数或参数类型出错”,如下图: 反复检查,存储过程的参数个数和参数类型都没错,觉得非常蹊跷.最后终于解决, 原因是当参数的值为nul ...