jsp中使用简单标签实现自定义表签
说明:
使用简单标签需要继承SimpleTagSupport类,这个类简化了对标签的开发
知识点:
【
SimpleTag方法介绍:
setJspContext方法
用于把JSP页面的pageContext对象传递给标签处理器对象
setParent方法
用于把父标签处理器对象传递给当前标签处理器对象
getParent方法
用于获得当前标签的父标签处理器对象
setJspBody方法
用于把代表标签体的JspFragment对象传递给标签处理器对象
doTag方法
用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容等。在doTag方法中可以抛出javax.servlet.jsp.SkipPageException异常,用于通知WEB容器不再执行JSP页面中位于结束标记后面的内容,这等效于在传统标签的doEndTag方法中返回Tag.SKIP_PAGE常量的情况。
SimpleTag接口方法的执行顺序:
当web容器开始执行标签时,会调用如下方法完成标签的初始化
WEB容器调用标签处理器对象的setJspContext方法,将代表JSP页面的pageContext对象传递给标签处理器对象。
WEB容器调用标签处理器对象的setParent方法,将父标签处理器对象传递给这个标签处理器对象。注意,只有在标签存在父标签的情况下,WEB容器才会调用这个方法。
如果调用标签时设置了属性,容器将调用每个属性对应的setter方法把属性值传递给标签处理器对象。如果标签的属性值是EL表达式或脚本表达式,则WEB容器首先计算表达式的值,然后把值传递给标签处理器对象。
如果简单标签有标签体,容器将调用setJspBody方法把代表标签体的JspFragment对象传递进来。
执行标签时:
容器调用标签处理器的doTag()方法,开发人员在方法体内通过操作JspFragment对象,就可以实现是否执行、迭代、修改标签体的目的。
JspFragment类:
javax.servlet.jsp.tagext.JspFragment类是在JSP2.0中定义的,它的实例对象代表JSP页面中的一段符合JSP语法规范的JSP片段,这段JSP片段中不能包含JSP脚本元素。
WEB容器在处理简单标签的标签体时,会把标签体内容用一个JspFragment对象表示,并调用标签处理器对象的setJspBody方法把JspFragment对象传递给标签处理器对象。JspFragment类中只定义了两个方法,如下所示:
getJspContext方法
用于返回代表调用页面的JspContext对象.
publicabstractvoidinvoke(java.io.Writerout)
用于执行JspFragment对象所代表的JSP代码片段
参数out用于指定将JspFragment对象的执行结果写入到哪个输出流对象中,如果传递给参数out的值为null,则将执行结果写入到JspContext.getOut()方法返回的输出流对象中。(简而言之,可以理解为写给浏览器)
invoke方法详解:
JspFragment.invoke方法可以说是JspFragment最重要的方法,利用这个方法可以控制是否执行和输出标签体的内容、是否迭代执行标签体的内容或对标签体的执行结果进行修改后再输出。例如:
在标签处理器中如果没有调用JspFragment.invoke方法,其结果就相当于忽略标签体内容;
在标签处理器中重复调用JspFragment.invoke方法,则标签体内容将会被重复执行;
若想在标签处理器中修改标签体内容,只需在调用invoke方法时指定一个可取出结果数据的输出流对象(例如StringWriter),让标签体的执行结果输出到该输出流对象中,然后从该输出流对象中取出数据进行修改后再输出到目标设备,即可达到修改标签体的目的。
】
第一步:编写SimpleTag继承SimpleTagSupport
publicclassSimpleTagextendsSimpleTagSupport{
publicvoiddoTag()throwsJspException,IOException{
//执行标签体
/*
JspFragmentbody=getJspBody();
JspWriterout=this.getJspContext().getOut();
body.invoke(out);
*/
//不执行标签体
//重复执行
/*JspFragmentbody=getJspBody();
JspWriterout=this.getJspContext().getOut();
for(inti=0;i<5;i++)
{
body.invoke(out);
}*/
//修改标签体内容
/*JspFragmentbody=getJspBody();
StringWriterout=newStringWriter();
//执行标签体,把内容传入流中
body.invoke(out);
Stringstr=out.toString();
str=str.toUpperCase();
getJspContext().getOut().write(str);*/
//停止显示标签后面文档内容
super.doTag();
thrownewSkipPageException();
}
}
第二步:编写一个view.tld文件
<?xmlversion="1.0"encoding="UTF-8"?>
<taglibxmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2eehttp://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>AtaglibraryexercisingSimpleTaghandlers.</description>
<tlib-version>1.0</tlib-version>
<short-name>SimpleTagLibrary</short-name>
<uri>http://www.liyong.simpletag</uri>
<tag>
<description>showclientIP</description>
<name>tag</name>
<tag-class>com.liyong.simpleTag.SimpleTag</tag-class>
<!--标签体不为空这与传统标签不同JSP-->
<body-content>scriptless</body-content>
</tag>
<tag>
<description>showclientIP</description>
<name>tag2</name>
<tag-class>com.liyong.simpleTag.SimpleTag</tag-class>
<!--标签体为空这与传统标签同empty-->
<body-content>empty</body-content>
</tag>
</taglib>
第三步:编写jsp并导入*.tld库
<%@pagelanguage="java"import="java.util.*"pageEncoding="UTF-8"%>
<%@tagliburi="/WEB-INF/simptag/view.tld"prefix="simple"%>
<%
Stringpath=request.getContextPath();
StringbasePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!--不执行页面内容-->
<%--
<simple:tag2/>
-->
<!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN">
<html>
<head>
<basehref="<%=basePath%>">
<title>MyJSP'simpletag.jsp'startingpage</title>
<!--
<linkrel="stylesheet"type="text/css"href="styles.css">
-->
</head>
<body>
<!--
显示标签体
<simple:tag>
test!!
</simple:tag>
-->
<%--
重复执行标签体内容
<simple:tag>
aaaaa
</simple:tag>
--%>
<%--
<simple:tag>
改变标签体内容
aaaaa
</simple:tag>
--%>
</body>
</html>
第四步:测试...