SimpleTag标签
定义了五个方法:setJspContext、setJspBody、setParent和getParent以及最重要的doTag方法(完成了所有的业务逻辑);
- setJspContext方法:将JSP页面的pageContext对象传递给标签处理器对象
- setJspBody方法:将代表标签体的JspFragment对象传递给标签处理器对象
- setParent方法:将父标签处理器对象传递给当前标签处理器
- getParent方法:获取当前标签的服标签处理器对象
- doTag方法:用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容等
SimpleTag接口提供了一个默认的实现类SimpleTagSupport,因此在编写时继承和扩展该类即可,再根据业务重写doTag方法;
范例:是否输出jsp页面的某一部分:
标签处理器类:()
public void doTag() throws JspException, IOException { //得到代表jsp标签体的JspFragment JspFragment jspFragment = this.getJspBody(); //得到jsp页面的的PageContext对象 PageContext pageContext = (PageContext) jspFragment.getJspContext(); //调用JspWriter将标签体的内容输出到浏览器 jspFragment.invoke(pageContext.getOut()); //将标签体的内容输出到浏览器 jspFragment.invoke(null); }
提供了两种方法输出标签体内容;而标签体内容如下:
<%@taglib uri="/xxx" prefix="ttt" %> <ttt:tagname> xiao兆 </ttt:tagname>
进行多次输出:
public void doTag() throws JspException, IOException { // 得到代表jsp标签体的JspFragment JspFragment jspFragment = this.getJspBody(); for (int i = 0; i < 5; i++) { // 将标签体的内容输出到浏览器 jspFragment.invoke(null); } }
修改标签体的内容:
public void doTag() throws JspException, IOException { // 得到代表jsp标签体的JspFragment JspFragment jspFragment = this.getJspBody(); StringWriter sw = new StringWriter(); //将标签体的内容写入到sw流中 jspFragment.invoke(sw); //获取sw流缓冲区的内容 String content = sw.getBuffer().toString(); content = content.toUpperCase(); PageContext pageContext = (PageContext) this.getJspContext(); //将修改后的content输出到浏览器中 pageContext.getOut().write(content); }
需要将结果写入一个自定义的缓冲区中,再将缓冲区的内容进行修改后进行输出即可;
控制余下的jsp页面是否执行:
public void doTag() throws JspException, IOException { //抛出一个SkipPageException异常就可以控制标签余下的Jsp不执行 throw new SkipPageException(); }
jsp页面范例:
<body> <h1>xiao兆</h1> <%--在jsp页面中使用自定义标签 --%> <ttt:tagname/> <!-- 这里的内容位于 <ttt:tagname/>标签后面,因此不会输出到页面上 --> <h1>learn</h1> </body>
标签库
我们在编写标签库时,标签有一个子元素<body-content>,表示标签体的内容,有四种类型:empty、JSP、scriptless、tagdependent;
而在编写简单标签时是不允许设置JSP类型的;
其各自代表的含义是:
empty:表示没有标签体;
scriptless:表示有标签体,且标签体不可以是java代码;
JSP:表示有标签体,且标签体可以是java代码,不过使用java代码的话其实就失去了自定义标签的意义了;
tagdependent:表示该标签体的内容是给标签处理器使用的,用的比较少;
注意标签库的uri不能设置相同的,所以在设置时候最好带上tld文件的所在目录,降低uri重复的可能性;
JspFragment类
web容器在处理简单标签时,会把标签体内容用一个JspFragment对象表示,并调用setJspBody方法把其传递给标签处理器对象,JspFragment类中只定义了两种方法:
getJspContext方法:返回调用页面的JspContext对象;
invoke方法:控制是否执行输出、迭代标签体内容或修改后输出,如没调用,则相当于忽略标签体内容;
带属性的标签体:
<ttt:tagname count = "5"> xiao兆 </ttt:tagname>
类似上面这种,包含count属性的标签体,其中count可在标签处理器充当一个变量,并通过Jsp页面中的标签体属性赋值给它,如果是8种基本数据类型,在JSP传递字符串时会自动改成相应的类型,不过如同date之类的复合数字类型,则不会进行自动转换,可通过表达式的方式给复合属性赋值,如:
<% Date d = new Date(); request.setAttribute("date", d); %> <gacl:demo6 date="${date}"/>
自定义标签的每个属性都要对应一个<attribute>元素,位于<tag>元素里面,<attribute>元素也有多个子元素,用于描述每个属性: