JSP简单标签标签库开发
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容器开始执行标签时,会调用如下方法完成标签的初始化:
- WEB容器调用标签处理器对象的setJspContext方法,将代表JSP页面的pageContext对象传递给标签处理器对象。
- WEB容器调用标签处理器对象的setParent方法,将父标签处理器对象传递给这个标签处理器对象。注意,只有在标签存在父标签的情况下,WEB容器才会调用这个方法。
- 如果调用标签时设置了属性,容器将调用每个属性对应的setter方法把属性值传递给标签处理器对象。如果标签的属性值是EL表达式或脚本表达式,则WEB容器首先计算表达式的值,然后把值传递给标签处理器对象。
- 如果简单标签有标签体,WEB容器将调用setJspBody方法把代表标签体的JspFragment对象传递进来。
- 执行标签时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简单标签标签库开发的更多相关文章
- javaweb学习总结(二十六)——jsp简单标签标签库开发(二)
一.JspFragment类介绍 javax.servlet.jsp.tagext.JspFragment类是在JSP2.0中定义的,它的实例对象代表JSP页面中的一段符合JSP语法规范的JSP片段, ...
- javaweb(二十六)——jsp简单标签标签库开发(二)
一.JspFragment类介绍 javax.servlet.jsp.tagext.JspFragment类是在JSP2.0中定义的,它的实例对象代表JSP页面中的一段符合JSP语法规范的JSP片段, ...
- jsp简单标签开发(一)
孤傲苍狼 @Override22 public void doTag() throws JspException, IOException {23 //得到代表jsp标签体的JspFragment24 ...
- javaweb学习总结(二十七)——jsp简单标签开发案例和打包
一.开发标签库 1.1.开发防盗链标签 1.编写标签处理器类:RefererTag.java 1 package me.gacl.web.simpletag; 2 3 import java.io.I ...
- javaweb学习总结(二十五)——jsp简单标签开发(一)
一.简单标签(SimpleTag) 由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的推广, SUN公司为降低标签技术的学习难度,在JSP 2.0中定义了一个更为简单.便于编 ...
- jsp 简单标签开发
实现simpleTag接口的标签通常称为是简单标签,简单标签一共定义了5个方法 setJspContext方法 setParent方法 getParent方法 setJspBody方法 doTag方法 ...
- JSP简单标签开发
一.继承自SimpleTag接口的自定义标签实现类称为简单标签,接口中5个方法 1.setJspContext方法 用于把JSP页面的PageContext对象传递给标签处理器对象 2.setPare ...
- JSP内置标签 JSP中JavaBean标签 JSP开发模式 EL和JSTL快速入门
2 JSP内置标签(美化+业务逻辑) 1)为了取代<%%>脚本形式,使用JSP标签/JSP动作,目的:与JSP页面的美化,即JSP面页都是由标签组成,不再有其它的内容 2)JSP内 ...
- 学会怎样使用Jsp 内置标签、jstl标签库及自定义标签
学习jsp不得不学习jsp标签,一般来说,对于一个jsp开发者,可以理解为jsp页面中出现的java代码越少,对jsp的掌握就越好,而替换掉java代码的重要方式就是使用jsp标签. jsp标签的分 ...
随机推荐
- Linux常用使用技巧
一.如何实时查看linux下的日志 cat /var/log/*.log 如果日志在更新,如何实时查看 tail -f /var/log/messages 还可以使用 watch -d -n 1 ca ...
- 2016 SyScan360 国际前瞻信息安全会议 多角度探讨信息安全
SyScan360国际前瞻信息安全会议由与中国第一大互联网安全公司-360公司与SyScan前瞻信息安全技术年会(TheSymposiumonSecurityforAsiaNetwork,以下简称Sy ...
- JavaScript功能规划的基本语法总结
1.迭代数组 1)map 方法会迭代数组中的每一个元素,并根据回调函数来处理每一个元素,最后返回一个新数组.注意,这个方法不会改变原始数组 //例子 var oldArray = [1,2,3,4,5 ...
- <hr/>标签改变颜色注意事项
1.css改变颜色 <hr style="border:0;background-color:#093;height:1px;"> 注意: 如果不加border:0 ...
- Dokan[转]
原文地址:http://www.cnblogs.com/xxonehjh/p/3634889.html 因工作需要,最近与同事合作使用Dokan开发了一个虚拟磁盘的简单程序,初步实现了远程目录映射到本 ...
- AR9531的mac地址
root@OpenWrt:/# ifconfigbr-lan Link encap:Ethernet HWaddr 00:11:22:34:56:78 inet addr ...
- c++的复制构造函数
在C++中,下面三种对象需要调用拷贝构造函数(有时也称“复制构造函数”): 1) 一个对象作为函数参数,以值传递的方式传入函数体: 2) 一个对象作为函数返回值,以值传递的方式从函数返回: 3) 一个 ...
- 日志输出--C#
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- ArrayList和LinkedList和Vector源码分析
ArrayList源码: private static final int DEFAULT_CAPACITY = 10;//默认长度 /** * Shared empty array instance ...
- photoshop cs6 mac版
首选项 -> 界面,调整工作区背景色 放大:command + "+" 放大镜:z 矩形选框工具(M):用来抠图,做造型.shift正方形选取 填充前景色:alt + del ...