java web 自定义标签_JavaWeb学习——自定义标签

自定义标签

一、自定义标签概述

使用标准JSP访问、操作JavaBean,是实现展现(HTML)与业务实现(Java代码)分离的第一步。然而,标准方法功能不够强大,以至于开发者无法仅仅使用它们开发应用,还要在JSP页面中使用Java代码。

介于JavaBean中解决展现与业务实现分离的方法的不完善,就产生了JSP1.1中的自定义标签。自定义标签提供了在JavaBean中所不能实现的便利。其中就包括,自定义标签允许访问JSP隐藏的对象及它们的属性。

尽管自定义标签能编写无脚本的JSP页面,但是JSP1.1和JSP1.2中提供的经典自定义标签非常难用。直到JSP2.0,才增加两个特性,用于改善自定义标签实现。第一个特性是一个接口——SimpleTag。另一个特性是标签文件中定义标签的机制。

自定义标签的实现,叫做标签处理器,而简单标签处理器是指继承SimpleTag实现的标签处理器。

二、简单标签处理器

实现SimpleTag的标签处理器都叫作简单标签处理器;实现Tag、Iteration及BodyTag的标签处理器都叫作经典标签处理器。

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

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

JSP容器通过简单标签处理器的无参数构造器创建它的实例。

JSP容器通过setJspContext的方法,传入JspContext对象。

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

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

如果需要处理页面内容,JSP容器还会调用SimpleTag接口的setJspBody方法,把使用JSPFragment封装的页面内容传过来。

javax.servlet.jsp.tagext 包中也包含了一个SimpleTag的基础类:SimpleTagSupport。它提供了SimpleTag所有方法的默认实现。

三、实例

自定义标签需要有两个步骤:编写标签处理器及注册标签。

1. 编写标签处理器

packagecustomtag;importjava.io.IOException;importjava.util.StringTokenizer;importjavax.servlet.jsp.JspContext;importjavax.servlet.jsp.JspException;importjavax.servlet.jsp.JspWriter;importjavax.servlet.jsp.tagext.SimpleTagSupport;public class DataFormatterTag extendsSimpleTagSupport {private String header; //标签属性

privateString items;public voidsetHeader(String header) {this.header =header;

}public voidsetItems(String items) {this.items =items;

}public void doTag() throws IOException, JspException { //标签处理函数

JspContext jspContext = getJspContext(); //返回JspFragment关联的JspContext对象

JspWriter out = jspContext.getOut(); //通过JspContext实例中的getOut方法获取JspWriter对象

out.print("

" + header +"

StringTokenizer tokenizer= new StringTokenizer(items,",");while(tokenizer.hasMoreElements()) {

String token=tokenizer.nextToken();

out.print("

" + token + "\n");

}

out.print("

");

}

}

2. 注册标签

Simple tag examples

1.0

1.1

My First Taglib Example

/firstTag

dataFormatter

customtag.DataFormatterTag

empty

header

true

items

true

3. 在JSP页面中使用自定义标签

1

2

3

4

5

TestingFormatterTag

6

7

8

9

10

11

12

13

14 US,UK,Canada,Korea15

16

17

18

19

运行效果:

0a66ed24870f3f28a6e2d4f0eea6552f.png

四.处理属性

实现SimpleTag接口或者扩展SimpleTagSupport的标签处理器都可以有属性。下面的例子展示了名为DateFormatTag的标签处理器可以将逗号分隔内容转换成HTML表格。

①标签处理器

1 packagecustomtag;2

3 importjava.io.IOException;4 importjava.util.StringTokenizer;5

6 importjavax.servlet.jsp.JspContext;7 importjavax.servlet.jsp.JspException;8 importjavax.servlet.jsp.JspWriter;9 importjavax.servlet.jsp.tagext.SimpleTagSupport;10

11 public class DataFormatterTag extendsSimpleTagSupport {12 privateString header;13 privateString items;14

15 public voidsetHeader(String header) {16 this.header =header;17 }18

19 public voidsetItems(String items) {20 this.items =items;21 }22

23 public void doTag() throwsIOException, JspException {24 JspContext jspContext =getJspContext();25 JspWriter out =jspContext.getOut();26

27 out.print("

" + header +"
" + token + "

34 out.print("

");35 }36 }

②jsp页面实现

TestingFormatterTag

US,UK,Canada,Korea

③效果展示

9d404dac31df93dc0aad77cace7d0c38.png

五.访问标签内容

在SimpleTag中,可以通过JSP容器传入的JspFragment来访问标签内容。JspFragment类提供了多次访问Jsp中这部分代码的能力。JSP片段的定义不能包含脚本或者脚本表达式,他只能是文件模板或者JSP标准结点。

JspFragment类中有两个方法:getJspContext、invoke。定义如下:

public abstractJspContext getJspContext()public abstract voidinvoke(java.io.Writer writer)throws JspException, java.io.IOException

getJspContext方法返回这个JspFragment关联的JspContext对象。可以通过invoke方法来执行这个片段(标签的内容),然后通过指定的Writer对象把它直接输出。如果把null传入invoke方法中,那么这个Writer将会被JspFragment所关联的JspContext对象中的getOut方法返回的JspWriter所接管。下面看一个示例:

SelectElementTag

packagecustomtag;importjava.io.IOException;importjavax.servlet.jsp.JspContext;importjavax.servlet.jsp.JspException;importjavax.servlet.jsp.JspWriter;importjavax.servlet.jsp.tagext.SimpleTagSupport;public class SelectElementTag extendsSimpleTagSupport{private String[] countries = {"Australia", "Brazil", "China"};public void doTag() throwsIOException, JspException {

JspContext jspContext=getJspContext();

JspWriter out=jspContext.getOut();

out.print("\n");for(int i=0;i<3;i++){

getJspContext().setAttribute("value", countries[i]);

getJspContext().setAttribute("text", countries[i]);

getJspBody().invoke(null);

}

out.print("\n");

}

}

注册SelectElementTag

select

customtag.SelectElementTag

scriptless

selectElementTagTest页面

Testing SelectElementFormatterTag

${text}

效果

40a65c3cbf2f6e03e744d37046ec0cbc.png

六、编写EL函数

一般来说,编写EL函数需要以下两个步骤:

(1)创建一个包含静态方法的public类。每个类的静态方法表示一个EL函数。这个类可以不需要实现任何接口或者继承特定的类。可以像发布任何类一样发布这个类。这个类必须放在应用中的/WEB-INF/classes目录或者它的子目录下。

(2)用function节点在标签库描述其中注册这个函数。

function节点是taglib节点的下级节点,它有如下子节点:

description:可选,标签说明。

display-name:在XML工具中显示的缩写名字。

icon:可选,在XML工具中使用的icon节点。

name:函数的唯一名字。

function-class:该函数对应实现的Java类的全名。

function-signature:该函数对应实现的Java静态方法。

example:可选,使用该函数的示例说明。

function-extension:可以是一个或者多个节点,在XML工具中使用,用于提供该函数的更多的细节。

要使用这个函数,必须将taglib指令中的URI属性指向标签库描述,并指明使用的前缀。然后在JSP页面中使用如下语法来访问该函数:

${ prefix:functionName(parameterList) }

具体看以下示例:

StringFunction类中的reverseString方法

packagefunction;public classStringFunctions {public staticString reverseString(String s){return newStringBuffer(s).reverse().toString();

}

}

functiontags.tld文件

Function tag examples

1.0

Reverses a String

reverseString

function.StringFunctions

java.lang.String reverseString(java.lang.String)

使用EL函数

Testing reverseString function

效果

9d01b4c0d4287c82964be9fc00958e13.png

七、发布自定义标签

可以吧自定义的标签处理器以及标签描述器打包到JAR包里,这样就可以把它发布出来给别人使用了,就像JSTL一样。这种情况下,需要包含其所有的标签处理器及描述它们的TLD文件。此外,还需要在描述其中的URI节点中指定绝对的URI。

为了在应用中使用这个库,需要把这个JAR文件拷贝到应用的WEB-INF/lib目录下。在使用的时候,任何使用自定义标签的JSP页面都要使用和这个标签库描述器中定义的URL。

------ 天若有情天亦老,人间正道是沧桑 ------

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/266475.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

739. Daily Temperatures - LeetCode

Question 739. Daily Temperatures Solution 题目大意&#xff1a;比今天温度还要高还需要几天 思路&#xff1a;笨方法实现&#xff0c;每次遍历未来几天&#xff0c;比今天温度高&#xff0c;就坐标减 Java实现&#xff1a; public int[] dailyTemperatures(int[] temperatur…

Android 抽屉效果Demo

2019独角兽企业重金招聘Python工程师标准>>> Android 抽屉效果Demo。 转载:http://www.adobex.com/android/source/details/00000110.htm 转载于:https://my.oschina.net/androidcode/blog/103821

DIV中文字不换行解决办法

解决办法如下&#xff1a;word-wrap &#xff1a; normal | break-word设置或检索当当前行超过指定容器的边界时是否断开转行。normal&#xff1a;控制连续文本换行。break-word&#xff1a;内容将在边界内换行。如果需要&#xff0c;词内换行&#xff08;word-break&#xff0…

python竞赛试题及答案_竞赛信息 | 蓝桥杯大赛Python组

蓝桥杯大赛 青少年创意编程Python组 竞赛规则及样题 — 竞赛规则 — 1 竞赛时长 Python编程组竞赛的选拔赛、省赛及国赛&#xff0c;竞赛时长均为120分钟&#xff0c;详细赛程安排另行通知。 2 竞赛形式 竞赛形式为个人赛&#xff0c;一人一机。 选手须自带笔记本计算机&#x…

Civil 3D 中使用COM API导入DEM数据创建曲面

Civil 3D提供的基于.net的API和基于COM的API&#xff0c;现在推荐大家使用.net API,但有时也需要使用COM API。 这个例子演示如何使用COM API来导入DEM数据生成Civil 3D曲面。 Civil 3D开发中使用COM API需要添加的引用比较啰嗦&#xff0c;建议使用向导创建项目简化操作&#…

牛客网第4场A

链接&#xff1a;https://www.nowcoder.com/acm/contest/142/A 来源&#xff1a;牛客网题目描述 A ternary string is a sequence of digits, where each digit is either 0, 1, or 2. Chiaki has a ternary string s which can self-reproduce. Every second, a digit 0 is i…

谈谈NiTE 2手部跟踪在彩色图像上的显示

主要内容&#xff1a; NiTE2手部跟踪流程代码演示总结一、NiTE2手部跟踪流程 我自己都感觉到天天在重复着相同的代码&#xff0c;但我觉得没什么不好的&#xff0c;对于新东西的学习只有在重复再重复的过程中&#xff0c;才能积累经验&#xff0c;较少犯“低级错误”的几率&…

java 应用是单机集群_【架构】Tomcat单机部署多应用Windows

Tomcat单机部署多应用-Windows1、添加新增的Tomcat相关环境变量CATALINA_BASE C:\tomcat1CATALINA_HOME C:\tomcat1TOMCAT_HOME C:\tomcat1CATALINA_2_BASE C:\tomcat2CATALINA_2_HOME C:\tomcat2TOMCAT_2_HOME C:\tomcat22、第一个tomcat不变3、打开第二个tomcat目录bin…

java long类型转string_JavaSE的学习——数据类型

数据类型分为基本数据类型和引用数据类型两大类在下面数据类型的介绍中只会介绍8种基本数据类型和引用数据类型中的类类型中的一个类String基本数据类型1. 计算机中的存储单位8bit 1byte 1024byte 1KB 1024KB 1M1024M 1GB1024GB 1T2. 整数型数据byte short int long1.long…

DWTagList

2019独角兽企业重金招聘Python工程师标准>>> DWTagList 根据给定的 NSArray 数组来创建标签列表&#xff0c;可自定义字体、颜色和其他属性。 转载:http://www.adobex.com/ios/source/details/00000820.htm 转载于:https://my.oschina.net/u/868244/blog/106245

爬虫(爬虫原理与数据抓取)

通用爬虫和聚焦爬虫 根据使用场景&#xff0c;网络爬虫可分为 通用爬虫 和 聚焦爬虫 两种. 通用爬虫 通用网络爬虫 是 捜索引擎抓取系统&#xff08;Baidu、Google、Yahoo等&#xff09;的重要组成部分。主要目的是将互联网上的网页下载到本地&#xff0c;形成一个互联网内容的…

SQL Server Insert 操作效率(堆表 VS 聚集索引表)

“SQL Server的Insert操作在堆表或者聚集索引表的时候&#xff0c;哪个效率更高&#xff1f;为什么高&#xff1f;” 之前有同事问过我这个问题&#xff0c;为了确保日志库的记录效率&#xff0c;于是我做了简单测试了&#xff0c;首先要先强调几点概念&#xff1a; 堆表&#…

electron 打包_Vue3+Electron整合方式

教程源码&#xff1a;nofacer/vue3-electron​github.com之前写过一篇文章Vue结合Electron构建跨平台应用&#xff08;TDD&#xff09;。当时的方法后来发现了一个问题&#xff0c;就是打包后的应用拿到其他机子上没法用&#xff0c;原因在于index.html的地址是个绝对路径&…

Linux按照时间顺序列出文件

按照递增时间顺序列出所有文件 ls -ltr -l表示列出长串数据&#xff0c;-t表示按照时间顺序&#xff0c;-r表示将排序的结果反向输出 按照时间递减的顺序列出所有文件 ls -lt 转载于:https://www.cnblogs.com/yongjieShi/p/9395932.html

RestKit

2019独角兽企业重金招聘Python工程师标准>>> Restkit 是一个开源的 objective-c 框架&#xff0c;允许在 iOS 和 Mac OS X 的 Objective-C 中与 RESTful Web 服务进行交互&#xff0c;包含简单的 HTTP request/response API &#xff0c;带有强大的对象映射系统用于…

全国计算机等级考试题库二级C操作题100套(第41套)

更多干货推荐可以去牛客网看看&#xff0c;他们现在的IT题库内容很丰富&#xff0c;属于国内做的很好的了&#xff0c;而且是课程刷题面经求职讨论区分享&#xff0c;一站式求职学习网站&#xff0c;最最最重要的里面的资源全部免费&#xff01;&#xff01;&#xff01;点击进…

2012年终总结 二

2019独角兽企业重金招聘Python工程师标准>>> 接上文。。。 经过一些搜索和了解之后&#xff0c;最后选定了我现在这个公司。现在&#xff0c;至少我没有感觉到我选错。 刚近公司&#xff0c;进行了新人的入职培训1天&#xff0c;这个主要是了解公司状况。而后&…

python语言包括哪些实现_Python语言基础考察点:python语言基础常见考题(一)

一、python是静态还是动态类型&#xff1f;是强类型还是弱类型&#xff1f; 1、动态强类型语言(不少人误以为是弱类型) 不要傻傻分不清 2、动态还是静态指的是编译期还是运行期确定类型 3、强类型指的是不会发生隐式类型转换 若类型语言强类型语言4、python作为后端语言优缺点 …

由于开发者通过接口修改了菜单配置_开发者说:Seata 0.7.0 版本,你 get 'Metrics' 技能了吗?...

从用户的视角来感受一个开源项目的成长&#xff0c;是我们推出「开发者说」专栏的初衷&#xff0c;即在开发者进行开源项目选型时&#xff0c;提供更为立体的项目信息。专栏所有内容均来自作者原创/投稿&#xff0c;本文是「开发者说」的第9篇&#xff0c;作者郑扬勇&#xff0…

Java 多线程(三) 线程的生命周期及优先级

Java 多线程&#xff08;三&#xff09; 线程的生命周期及优先级 线程的生命周期 线程的生命周期&#xff1a;一个线程从创建到消亡的过程。 如下图&#xff0c;表示线程生命周期中的各个状态&#xff1a; 线程的生命周期可以分为四个状态&#xff1a; 1.创建状态&#xff1a; …