java web 自定义标签_javaweb 自定义标签
我们一般以如下方式引入一个标签
这时再在jsp中写相对应的标签就行了,那么我们如何定义自己的标签类呢?首先我们需要来了解如下三个类
TagSupport
BodyTagSupport
SimpleTagSupport
为了更好的理解,我们先手写个示例
package com.cmh.tag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.TagSupport;
public class MyTagTest extends TagSupport {
private PageContext pageContext;
@Override
public void setPageContext(PageContext pageContext) {
this.pageContext = pageContext;
}
@Override
public int doStartTag() throws JspException {
try {
pageContext.getResponse().getWriter()
.write(“这是我写的一大段信息:ABCDEFGHIJKLMNOPQRSTUVWXYZ\n”);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return super.doStartTag();
}
}
然后我们在Web-INF 文件夹下添加tld文件,如下
1.0
1.2
mtt
http://vmaxtam.com/mytag
mytah
com.cmh.tag.MyTagTest
JSP
再在jsp页面下添加我们的标签引用
好了大功告成
读取标签库的流程
首先jsp会转换为servlet java 代码
当servlet中读到了tag巷的时候,他会去内存中查找是否存在uri标签巷,不存在则抛异常
根据uri地址去查询相应的tld文件是否存在,不存在则抛异常
4.
实例化标签处理程序,利用生成的对象调用它里面的方法
这里服务器对标签处理程序里的方法也有一定的调用顺序 A)void setPageContext(PageContext pc) –传入pageContext对象
B)void setParent(Tag t) –如果有父标签,传入父标签对象,如果没有,则传入null
C)int doStartTag() –开始执行标签时调用。
D)int doEndTag() –结束标签时调用
E)void release() –释放资源
然而以上的TagSupport只是支持相对简单的包装,并不能获取标签里面的内容,所以这时为了解决这个历史版本的问题,BodyTagSupport就出现了,示package
com.cmh.timpojava.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTag;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.Tag;
public class MyTagBody extends BodyTagSupport {
private PageContext pageContext;
@Override
public void setPageContext(PageContext pageContext) {
this.pageContext = pageContext;
}
@Override
public int doStartTag() throws JspException {
//返回BodyTag.EVAL_BODY_BUFFERED,表示输出标签体内容
//返回Tag.SKIP_BODY,表示不输出内容
return BodyTag.EVAL_BODY_BUFFERED;
//return Tag.SKIP_BODY;
}
@Override
public int doEndTag() throws JspException {
//得到BodyContent对象,它包装了标签体里的内容
BodyContent bodyContent = this.getBodyContent();
//利用getString方法得到字符串
String content = bodyContent.getString();
//改变字符串内容,将小写改为大写
String change = content.toUpperCase();
//输出到浏览器
try {
this.pageContext.getResponse().getWriter().write(“\n”+change);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return Tag.SKIP_PAGE;
}
}
以获取标签里的内容进行更改了,不过看到上面是不是觉得很是麻烦,写那么多干嘛,这时为了简便优化操作,就诞生了SimpleTagSupport,代码示
package com.cmh.tag;
import java.io.IOException;
import java.io.StringWriter;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
public class SimpleTag extends SimpleTagSupport {
private Integer num;
public void setNum(Integer num) {
this.num = num;
}
@Override//当遇到标签时就会执行这个方法
public void doTag() throws JspException, IOException {
StringWriter writer = new StringWriter();
//4.2 把标签体内容拷贝到临时的Writer流中
JspFragment jspBody = this.getJspBody();
jspBody.invoke(writer);
//4.3 从临时的Writer流中取出标签体内容
String content = writer.toString();
//4.4 改变标签体内容
content = content.toUpperCase();
//4.5 把改变后的内容写出到浏览器中
//jspBody.invoke(null);如果这样写,那么还是输出原来的内容
this.getJspContext().getOut().write(content+num);
}
}
文件做相应的更改
simpletag
com.cmh.tag.SimpleTag
scriptless
num
true
true
记住在tld中body-content有几种类型
JSP: 表示输出的标签体内容可以包含jsp脚本,且可以执行此脚本。此值只能用在传统标签中。
scriptless: 表示输出的标签体内容不能包含jsp脚本,如果包含则报错。
empty:表示没有标签体内容。即是空标签。如果不是空标签,则报错。
tagdependent: 表示输出的标签体内容可以包含jsp脚本。但不执行jsp脚本(直接原样输出)
SimpleTagSupport的执行流程和前面两个有稍许不一样,如下
一)和传统标签一样,得到tag-class字符串,找到标签处理程序类
二)实例化标签处理程序类
三)利用对象调用方法。。。。
和传统标签相比,简单标签调用的方法不相同:
SimpleTag接口的方法执行过程:
1) void setJspContext(JspContext pc) –设置pageContext对象,传入pageContext对象。JspContext是PageContext的父类。在标签处理器类中通过this.getJspContext()方法得到PageContext对象。
2)void setParent(JspTag parent) –传入父标签对象,如果没有父标签,则不调用次方法。通过getParent方法得到父标签对象
3)void setJspBody(JspFragment jspBody) –传入标签体内容。标签体内容封装到JspFragment方法中。通过getJspBody方法得到标签体内容。如果没签体,不调用次方法。
4)void doTag() –开始标签和结束标签都执行次方法。
还没有评论,来说两句吧...