1. 说明
本文档是学习tomcat中例子的笔记,并没有参考相应的说明文档,因此不能保证本文观点的正确性。如果有不对之处,不妨email至8280338@tzenet.com,大家共同进步。
2. JSP2.0标签使用方法
JSP2.0中标签的使用由多个部分组成:
(1) WEB_INF/web.xml中添加标签引用
(2) 标签的实现,可能是class也可能是web templet
(3) 在jsp文件中添加引用
在实际使用中,分析jsp2.0标签可以先从jsp文件入手,然后再分析web.xml及相应的标签库文件。
2.2 基本标签的使用方法
2.2.1 jsp文件中的标签引用及使用方法
以下是一个简单的jsp文件:
<%@ taglib prefix="mytag" uri="/WEB-INF/jsp2/jsp2-example-taglib.tld" %>
<html> <body> <mytag:helloWorld/> </body></html>
说明:
(1) 首先以<%@ taglib prefix="mytag" uri="…" %>说明标签前缀及该前缀引用的标签所在路径,在这个例子中uri值是一个相对路径(本地路径),即当前项目根目录下WEB-INF/ jsp2/ jsp2-example-taglib.tld。如果使用的是本地路径就不需要在web.xml中配置路径映射了;
(2) 指定了标签前缀后,在jsp页面的body内就可以使用这个前缀来引用标签库中的指定标签了,如<mytag:helloWorld/>,就是引用mytag所指定的标签库中的helloWorld标签。
2.2.2 web.xml中的配置
如果在上述例子中使用的不是本地路径,那么就需要在web.xml中配置路径转换,如使用:<%@ taglib prefix="mytag" uri=" http://mytaglib/myTestTags1 " %>来引用标签库,那么就需要在web.xml文件的jsp-config节点中添加如下配置:
<taglib>
<taglib-uri>http://mytaglib/myTestTags1</taglib-uri>
<taglib-location>/WEB-INF/jsp2/jsp2-example-taglib.tld </taglib-location>
</taglib>
JSP解释器会将http://mytaglib/myTestTags1根据web.xml中的配置转化为本地路径。当然<taglib-uri>中文本可以是任何值,但不能和其它的配置冲突,所以在规划时最好加上前缀,如:http://mytaglib等。
2.2.3 标签库中的配置
在标签库中的配置实际上就是配置对实现类的引用,JSP解释器会根据jsp文件中对标签的引用,在标签库中找到相应的标签,然后再根据标签中的定义调用具体的实现类,本例中在jsp文件中对标签的引用:<mytag:helloWorld/>,即引用了helloWorld这个标签,这个标签在标签库中的定义如下:
<tag>
<description>Outputs Hello, World</description>
<name>helloWorld</name>
<tag-class>jsp2.examples.simpletag.HelloWorldSimpleTag</tag-class>
<body-content>empty</body-content>
</tag>
该标签由四个部分组成:
(1) description:描述该标签的作用
(2) name:标签的名字,该名字在jsp文件使用,相当由类名;
(3) tag-class:标签的实现索引,相当于类的实现;本例索引指定jsp2.examples.simpletag.HelloWorldSimpleTag,是一个java的类文件,应放在WEB_INF/classes/jsp2/examples/simpletag目录下的HelloWorldSimpleTag.class文件;
(4) body-content:在jsp文件中使用标签时,标签中的内容类别,本例的值是empty,表示helloWorld这个标签中没有内容。如果在jsp页面中在该标签中加入了内容,如<mytag:helloWorld>hell</mytag:helloWorld>,页面会报错,当然<mytag:helloWorld></mytag:helloWorld>是不会错的(注意不能有空格式)。
2.2.4 类的实现
类HelloWorldSimpleTag实现如下:
package jsp2.examples.simpletag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;
public class HelloWorldSimpleTag extends SimpleTagSupport {
public void doTag() throws JspException, IOException {
getJspContext().getOut().write( "Hello, world!" );
}}
说明:
(1) jsp标签调用的类一般继承于SimpleTagSupport
(2) SimpleTagSupport中实现了getJspContext()这个方法,这个方法可以获取指向jsp页面的输出流。
(3) getJspContext().getOut().write( "Hello, world!" ):输出Hellow,World!
2.3含有变量的tag配置
2.3.1 jsp文件中的标签引用及使用方法
以下是引用了带有变量标签的jsp页面:
<%@ taglib prefix="mytag" uri="/WEB-INF/jsp2/my_taglib.tld" %>
<html><body>
<mytag:repeat num1="15">
Invocation ${count} of 5<br>
</mytag:repeat>
</body>
</html>
说明:
(1) <mytag:repeat num="15">,输入参数的传入方法:即在标签中将要传入的参数做为标签的一个属性,并指定其属性值,本例中传入参数num1,它的值为15;
(2) ${count},在页面中显示输出参数的值,count是输出参数的名字
2.3.2 标签库中的配置
标签库中的相应配置如下:
<tag>
<description>Repeats the body of the tag 'num' times</description>
<name>repeat</name>
<tag-class>jsp2.examples.simpletag.RepeatSimpleTag</tag-class>
<body-content>scriptless</body-content>--标签内容是脚本
<variable>
<description>Current invocation count (1 to num)</description>
<name-given>count</name-given> --输出参数说明
</variable>
<attribute>
<name>num</name> --输入参数说明
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
该标签由六个部分组成:
(1) description:见上文
(2) name:见上文
(3) tag-class:见上文
(4) body-content:这个例子的值是scriptless,表示标签中的内容是脚本
(5) variable:输出参数,在jsp中使用${count}来引用这个输出变量的值,输出参数名并不是强制性的,这里只是一个约定,即要求repeat实现类最后有count这个输出参数,以便在jsp页中方便引用,如果没有也不会报错;
(6) attribute:输入参数,在jsp中使用< mytag:repeat num="5">来设置这个输入参数num,这个参数名是强制性的,即要在repeat实现类中有setNum这个方法,如果没有相应的方法jsp页面会报错;
2.3.3 类的实现
package jsp2.examples.simpletag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.util.HashMap;
import java.io.IOException;
public class RepeatSimpleTag1 extends SimpleTagSupport {
private int num;
public void doTag() throws JspException, IOException {
for (int i=0; i<num; i++) {
getJspContext().setAttribute("count", String.valueOf( i + 1 ) );
getJspBody().invoke(null);
} }
public void setNum(int num) {
this.num = num; }}
说明:
(1) getJspContext().setAttribute定义了输出到jsp页面的输出参数count,这里的count是一个字符串,它的值可以不与标签库中variable定义相同,如,它可以是len,当然在jsp引用时应以这里为准,即使用${len}引用;
(2) setNum(int num)方法:接收输入参数,这个方法命名规则为set+输入参数名,该方法带一个参数,用于接收输入参数的值。
2.4 函数标签的定义方法
2.4.1 jsp文件中函数标签引用及使用方法
<%@ taglib prefix="my" uri="/WEB-INF/jsp2/jsp2-example-taglib.tld" %>
<html>
<body><span>${my:caps(“HELLO WORLD”)}</span></body>
</html>
说明:
(1) 函数标签的引用比其它标签的引用都要简单,它的引用与高级语言中的函数调用方法类似,直接在函数名后的括号后面输入相应的参数值即可,不需要另加用标签的其它属性来说明输入参数。
2.4.2 函数标签在标签库中配置
<function>
<description>Converts the string to all caps</description>
<name>caps</name>
<function-class>jsp2.examples.el.Functions</function-class>
<function-signature>java.lang.String caps( java.lang.String )</function-signature>
</function>
说明如下:
(1) 这种方法的定义包含在function元素中;
(2) name:函数名
(3) function-class:该函数真正的实现class,本例中,caps函数是由WEB_INF/classes/ jsp2/examples/el路径中的Functions类来实现的;
(4) function-signature:说明函数的输入及输出参数类型,不用指明参数名。
2.4.3 类的实现
package jsp2.examples.el;
import java.util.*;
public class Functions {
public static String caps( String text ) {
return text.toUpperCase();
}}
说明:
(1) 函数标签实现类就是普通的类,它不需要从某个父类继承;
(2) 函数标签实现类中必须有相应的方法与标签库中相应的函数字义相同(包括函数名,输入参数个数及输入参数类型,函数的返回值);
2.5 标签模板
标签模板的特点:
(1) 没有tld文件在jsp中通过<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>引用,即使用tagdir代替了uri,这里的tags是一个文件夹,不是文件,在该文件夹中包含了所需的标签模板;
(2) 通过以下方式传入参数值:
<tags:displayProducts>
<jsp:attribute name="normalPrice">....</jsp:attribute>
<jsp:attribute name="onSale">....</jsp:attribute>
.....
</tags:displayProducts>
(3) displayProducts是与/WEB-INF/tags目录中的某个文件名;
(4) 通过<jsp:attribute name="…. ">来赋值
(5) 标签模板是一个纯文本文件,类似于html文件,而不需要通过java的类来实现标签的定义;
(6) 个人认为标签模板的主要作用重在排版,而其它标签的作用重在功能的实现;本人不打算在以后的开发使用标签模板,因此本文不再进一步分析标签模板。
3. 参考
http://localhost:8080/jsp-examples/