Tag file
JSP 2.0 引入 Tag file ,tag file 以 tag 或 tagx 为后缀,它们可以包含其他资源文件;一个被其他文件包含的 tag file 应该以 tagf 为后缀。
如同JSP页面被翻译成 Servlet 一样,JSP容器提供多种方式将 tag file 编译成 Java 的标签处理类。例如 Tomcat 将 tag file 翻译成继承与 javax.servlet.jsp.tagext.Simpletag 接口的标签处理类。
一个 Tag file 和 JSP 页面一样,拥有指令、脚本、EL表达式、动作元素、自定义的标签。
Tag file 从两方面简化了自定义标签的开发:
1)tag file 无需提前翻译,直到第一次被调用才会编译
2)不再需要标签库描述文件,使用 tag file 的方式,tag file 的文件名和标签名称(不包含后缀)相同。
tag file必须放在应用路径的 WEB-INF/tags 目录下才能生效。
tag file 中也有一些隐藏对象,通过脚本或者EL表达式可以访问这些隐藏对象。
request // javax.sevlet.http.HttpServletRequest response // javax.servlet.http.HttpServletResponse out // javax.servlet.jsp.JspWriter contig // javax.servlet.ServletContig session // javax.servlet.http.HttpSession application // javax.servlet.ServletContext jspContext // javax.servlet.jsp.JspContext
使用 tag file 的例子
在应用项目的 WEB-INF 下新建 tags 目录,然后再 tags 目录下新建 tag file
<%-- firstTag.tag --%> <%@ tag language="java" pageEncoding="UTF-8"%> <%@ tag import="java.util.Date" import="java.text.DateFormat" %> <% DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG); Date now = new Date(System.currentTimeMillis()); out.println(dateFormat.format(now)); %>
在 JSP 页面中使用 tag file
<%-- firstTagtest.jsp --%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib tagdir="/WEB-INF/tags" prefix="easy" %> <!-- 使用tagdir属性 --> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Test tag file</title> </head> <body> Today is <easy:firstTag /> <!-- 标签名和tag file名相同 --> </body> </html>
测试
Tag file 中的指令
和 JSP 页面一样,tag file 可以使用指令来指挥 JSP容器如何编译这个 tag file,tag file 的指令语法和 JSP是一样的
<%@ 指令名称 属性=“属性值” 属性=“属性值” %> tag <!-- 与JSP中的page指令作用相同 --> taglib <!-- 用于引入自定义标签库到 tag file 中 --> include <!-- 用于将其他资源导入 tag file 中 --> attribute <!-- --> variable <!-- -->
tag 指令 <%@ tag 属性=“属性值” ... %>
display-name // 在XML工具中显示的名称,默认值是不包含后缀的tag file名
body-content // 指定标签body的类型,body-content属性值有empty、tagdependent、scriptless,默认值是scriptless dynamic-attributes // 指定tag file动态属性的名称。当dynamic-attributes值被设定时,会产生一个Map来存放这些动态属性的名称和对应的值 small-icon // 指定一个图片路径,用于在XML工具上显示小图标。一般不会用到。 large-icon // 指定一个图片路径,用于在XML工具上显示大图标。一般不会用到。 description // 标签的描述信息 example // 标签使用实例的描述 language // tag file中使用的脚本语言类型,该值必须是“java” import // 用于导入一个java类型,和JSP页面中的import相同。 pageEncoding // 指定tag file的编码格式,可以使用“CHARSET”中的值。和JSP中的pageEncoding相同。
taglib 指令 <%@ taglib uri=''tagLibraryURL" prefix="tagPrefix"%>
tag file 中的taglib 指令和JSP页面中的taglib 指令是一样的。该指令只有两个属性:uri 和 prefix
include 指令 <%@ include file=“文件相对 uri 地址” %>
tag file 中的include指令和JSP中的include指令是一样的。可以有多个 include 指令,该指令只有一个 file 属性
<!-- includeDemoTag.tag --> This tag file shows the use of the include directive. The first include directive demonstrates how you can include a static resource called included.html. <br /> Here is the content of included.html: <%@ include file="included.html" %> <br /> <br /> The second include directive includes another dynamic resource: included.tagf <br /> <%@ include file="included.tagf" %> <!-- 导入到tag file中的tag file 必须以tagf为后缀 -->
<!-- included.html --> <table> <tr><td><b>Menu</b></td></tr> <tr><td>CDs</td></tr> <tr><td>DVDs</td></tr> <tr><td>Others</td></tr> </table>
<!-- included.tagf -->
<% out.print("Hello from included.tagf."); %>
<!-- includeDemoTagTest.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib tagdir="/WEB-INF/tags" prefix="easy" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Test include directive</title> </head> <body> <easy:includeDemoTag /> </body> </html>
attribute 指令 <%@ attribute 属性=“属性值” %>
用于设定 tag file 中标签的属性,将值从JSP页面中传递到tag file中。其和标签库描述文件中的atttribute元素等效
name // 用于设定该属性的名称。在一个 tag file 中,每个属性的名称必须是唯一的。 required // 用于设定该属性是否是必须的。值可以取 true 和 false 默认是 false fragment // 用于设定该属性是否是fragment,默认是 false rtexprvalue // 用于设定该属性的值是否在运行时被动态计算,值可以取 true 或 false 默认是 true type // 用于设定该属性的类型,默认是 java.lang.String description // 用于设定该属性的描述信息
<!-- encode.tag --> <%@ tag language="java" pageEncoding="UTF-8"%> <%@ attribute name="content" required="true" %> <%! private String encodeHtmlTag(String tag) { if (tag == null){ return null; } int length = tag.length(); StringBuilder encodedTag = new StringBuilder(2 * length); for(int i=0; i<length; i++){ char c = tag.charAt(i); if(c == '<'){ encodedTag.append("<"); } else if(c == '>'){ encodedTag.append(">"); } else if(c == '&'){ encodedTag.append("&"); } else if(c == '"'){ encodedTag.append("&qout"); } else if(c == ' '){ encodedTag.append(" "); } else { encodedTag.append(c); } } return encodedTag.toString(); } %> <%=encodeHtmlTag(content) %>
<!-- encodeTagTest.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib tagdir="/WEB-INF/tags" prefix="easy" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>encodedTagTest</title> </head> <body> <easy:encode content="<br /> means changing line" /> <br /> <easy:encode content="Today is Sunday." /> </body> </html>
variable 指令 <%@ variable 属性=“属性值” %>
将 tag file 中的一些值传递到JSP页面中,用于定义那些需要传递到JSP页面的变量
name-given // 变量名。在JSP页面的脚本和EL表达式中,可以使用该变量名。不能和name-from-attribute属性同时出现 name-from-attribute // 和name-given属性类似,由标签属性的值来决定变量的名称。不能和name-given属性同时出现 alias // 设定一个用来接收变量值的局部范围 varialbe-class // 变量的类型,默认为java.lang.String declare // 设定该变量是否声明,默认值为false scope // 用于指定该变量的范围。可取的值为AT_BEGIN、AT_END、NESTED。默认为NESTED description //用于描述该变量
<!-- varDemo.tag --> <%@ tag language="java" pageEncoding="UTF-8"%> <%@ tag import="java.util.Date" %> <%@ tag import="java.text.DateFormat" %> <%@ variable name-given="longDate" %> <%@ variable name-given="shortDate" %> <% Date now = new Date(System.currentTimeMillis()); DateFormat longFormat = DateFormat.getDateInstance(DateFormat.LONG); DateFormat shortFormat = DateFormat.getDateInstance(DateFormat.SHORT); jspContext.setAttribute("longDate", longFormat.format(now)); jspContext.setAttribute("shortDate", shortFormat.format(now)); %> <jsp:doBody /> <!-- 该动作元素用来调用这个标签体 -->
<!-- varDemoTest.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib tagdir="/WEB-INF/tags" prefix="tags" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>varDemoTest</title> </head> <body> Today's date: <br /> <tags:varDemo>In long format: ${longDate }</tags:varDemo> <br /> <tags:varDemo>In short format: ${shortDate }</tags:varDemo> </body> </html>
DoBody 动作元素
该动作元素只能在 tag file 中使用,用来调用一个标签的本体内容。
doBody动作元素也可以有属性,通过这些属性来指定某个变量来接收主体内容,如果不使用这些指令,那么 doBody 动作元素会把主体内容写到 JSP 页面的 JspWriter 上。
var // 用于保存标签主体内容的变量名,主体内容就会以java.lang.String的类型保存在这个变量内,var 和 varReader 属性只能出现一个 varReader // 用于保存标签主体内容的变量名,主体内容会以java.io.Reader的类型保存在这个变量内 scope // 变量保存到作用域
invoke动作元素
invoke动作元素和doBody动作元素类似,在 tag file 中,可以使用它来调用一个 fragment。
fragment // 要调用的fragment的名称 var // varReader // scope //