接上次说,在 JSP 中一般是不允许出现 Java 代码的,但有的时候必须要用 Java 代码来做一些输出,这时候可以使用自定义标签来实现,自定义标签对应一个 Java 类,JSP 引擎解析到标签的时候会执行对应类中相应的方法
传统标签
先来说说在 JSP2.0 之前的做法,虽然可能已经没人用了,但是了解一点没坏处啊,又不是很难,看框架的时候也许会用到呢
自定义标签需要实现 Tag 接口,这个接口非常简单,当然一般都是继承它的实现类 TagSupport 然后复写需要的方法
API 参考:https://tomcat.apache.org/tomcat-5.5-doc/jspapi/
下面是一个简单的例子:
1 | package web.tag; |
这里就简单写了个输出 IP 的例子,剩下的就是让这个类和标签关联起来,一般我们在 WEB-INF 目录下新建一个 tld 文件来指定,可以是多级目录下,但必须在 WEB-INF 下,如果用的是 IDEA 的话直接有现成的模板,实在不行可去抄 Tomcat 里的例子
1 | "1.0" encoding="ISO-8859-1" xml version= |
主要是配置 uri 和 tag 标签,下面在 JSP 中会用到 body-content 属性可以认为标签是否含有标签体,单标签双标签的区别,然后下面就是在 JSP 中进行引用了
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
prefix 一般写我们定义的那个 tld 的文件名,有利于查找
还有一点需要注意,自定义标签处理完后一般不会立即释放资源,也就是一般不会执行 release() 方法,和 Servlet 类似,也会被缓存,等待下一次访问,等 Web 服务器关闭的时候会释放资源
自定义标签扩展
自定义标签除了上面的用法,还有几种比较常用的方式,比如控制 JSP 的 某一部分/全部内容 是否执行,重复输出某些内容、修改某些内容等,从 JSP 的用法上看它们都是一样的,就是把要控制的内容放进自定义标签体里。
控制是否执行
JSP 文件就不多说了,把要控制的内容包进去就可以了,然后我们在 Java 代码中进行控制,至于怎么控制,那就是用 Start/End 方法的返回值了!在 API 文档中说的也比较详细了,Tag 接口中定义了几个常量
1 |
|
对了,还有,不要忘记在 WEB-INF 文件夹下的 tld 文件里修改 body-content 为 JSP
1 | <tag> |
重复执行
重复执行某段内容,Tag 接口就无能为力了,所以就有了 IterationTag 接口,是的,它是专门为了重复执行而设计的,在 Tag 的基础上加了一个常量和方法
TagSupport 类已经实现了这个接口,所以说,用到直接复写 doAfterBody() 方法就可以了
它的调用时机是在标签体执行完,doEndTag 方法执行前
如果返回 EVAL_BODY_AGAIN 继续重复执行( doAfterBody 方法也会重复执行);
返回的是 SKIP_BODY 继续向下执行,但是 doStartTag 方法只会执行一次,毕竟配对的 doEndTag 不会执行嘛
1 | private int i = 5; |
修改内容
如果想要修改内容的话,上面的两个接口都无能为力,只能靠 BodyTag 接口了,类似的我们一般是继承 BodyTagSupport 类然后复写需要的方法其实还是是 doStartTag() 只不过返回值不同了
1 | public class UpdateTag extends BodyTagSupport { |
简单标签
正是因为传统标签做不同的操作需要实现不同的接口太麻烦,所以在 JSP2.0+ 加入了SimpleTag 接口来统一,所有的功能实现这一个就可以了,不过我们还是习惯继承 SimpleTagSupport 类啦~
在简单标签中,解析时会先执行 setJspBody 方法把标签体的内容存起来 (当然还会自动调用 setParent [没有就会传 null ]、setJspContext 方法),然后执行 doTag() 方法
要注意的是:在简单标签中没有 Start/End 方法了,开始结束全都是执行 doTag;从 API 文档中可以知道,如果不想执行后面的内容,抛一个 SkipPageException 异常即可,相当于是传统标签的 SKIP_PAGE
1 | public class SimpleTag extends SimpleTagSupport { |
还要记得修改 body-content ,在 2.0+ 后要使用 scriptless,从名字也可以看得出,是不建议再在 JSP 中嵌入java 代码的
1 | <tag> |
基本上就是这样了..
自定义标签的属性
都知道 HTML 标签都有属性,自定义的应该也有嘛~,想要设置自定义属性一般需要两步
- 在对应的 Java 文件中编写对应的 Set 方法,程序会自动调用的,注意名称一致
- 配置 TLD 文件
下面就举个简单栗子,循环输出指定次数的标签体:
1 | public class SimpleAttributes extends SimpleTagSupport { |
只设置一个 Set 方法就行了,Get 没什么必要,下面就是配置 tld 文件了:
1 | <tag> |
required :表示是否是必须的
rtexprvalue:表示是否允许使用表达式(比如 ${name} )
type:指定类型,一般没必要设置
然后就可以在 JSP 中进行使用了,可以实现 防盗链、if判断、迭代、处理转义等功能,就如 EL 表达式一样,迭代功能写起来可能复杂点,不过利用反射技术挺方便的
PS:转义的实现在 \webapps\examples\WEB-INF\classes\util
下有现成的
最后,可以把这些自定义标签打成 jar 包,以后用到了直接丢进 lib 就行了,打包的时候建一个普通的 Java 工程就行,只要保证在 web 项目中没问题,拷贝到 Java 项目中后出现的错误不用管,是 J2EE 依赖的问题,然后把 tld 文件放在根目录下的 META-INF 目录就行,参考 Tomcat 中自带的 Jar 包结构。
评论框加载失败,无法访问 Disqus
你可能需要魔法上网~~