7.2、第一个标签文件
以下是项目结构图:
以下是代码清单:
这是firstTag.tag文件
<%@ tag import="java.util.Date" import="java.text.DateFormat" %>
<%
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL) ;
Date now = new Date(System.currentTimeMillis()) ;
out.println(dateFormat.format(now)) ;
%>
firstTagTest.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="easy" tagdir="/WEB-INF/tags" %>
<html>
<head>
<title>My JSP 'firstTagTest.jsp' starting page</title>
</head>
<body>
Today is <easy:firstTag></easy:firstTag>
</body>
</html>
项目执行截图:
7.3、标签文件指令
像jsp页面一样,标签文件能够利用指令来控制jsp容器怎样编译和转换标签文件。标签文件指令的语法与jsp指令的语法一样:
<%@ directive (attribure=”value”)* %>
星号(*)表示括号里的内容能够不反复,也能够反复多次。
这个语法能够用一种比較任意的方式进行改写:
<%@ directive attribute1=”value1” attribute2=”value2” ... %>
当中的属性必须用单引號或者双引號括起来。起始符号<%@后面的空格和结束符号%>前面的空格是可选的,只是使用空格能够提升可读性。
除了page之外,全部jsp指令在标签文件里都能够使用。这里不用page。而是用tag指令。
并且,在标签文件里,还有另外两个指令能够使用:attribute和variable。以下是能够在标签文件里使用的全部指令。
1、tag。该指令与jsp页面的page指令相似
2、include。
用这个指令包括来自标签文件的其它资源
3、taglib。
用这个指令从标签文件内部使用定制标签类库
4、attribute。用这个指令在标签文件里声明一个属性
5、variable用这个指令定义一个能够暴露给在调用jsp页面的变量
7.3.1、tag指令
Tag指令的语法:
<%@ tag (attribute=”value”)* %>
以上语法用非正式的能够表示为:
<%@ tag attribute1=”value1” attribute2=”value2” ... %>
Tag指令的属性为:
display-name:通过XML工具显示的简称,默认值为标签文件名称,没有tag扩展名。
body-content:关于这个标签主体内容的信息,它的值能够为empty、tagdependent或scriptless(默认)。
dynamic-attributes:表名对动态属性的支持。
它的值表示一个放置Map的有界属性,当中包括了这个调用期间传递的动态属性名和值
small-icon:XML工具要用到的小图片文件相对于context的路径,或者相对于标签资源文件的路径。我们通常不使用这个属性。
large-icon:包括XML工具要用到的大图标图片文件相对于context的路径,或者相对于标签资源文件的路径。我们通常也不使用这个属性。
description:描写叙述该标签的一个字符串。
example:该动作指令使用方法范例的一个非正式描写叙述。
language:标签文件里使用的脚本语言。该属性值在当前jsp版本号中必须为“java”
import:用于导入java类型,与page指令中的import属性同样。
pageEncoding:描写叙述该标签文件的字符编码,这个值的形式为“charset”,必须是字符编码的IANA名称。该属性与page指令的pageEncoding属性同样。
isELIgnored:表名忽略还是运算EL表达式,该属性的默认值为“false”,意为运算EL表达式,该属性与page指令的isELIgnored属性同样。
除了import属性之外,全部其它属性在同一个标签文件的一个tag指令或者多个tag指令中都仅仅能出现一次。比如,下面tag文件就是无效的。由于body-content属性不止一次地出如今多个tag指令中:
<%@ tag display-name=”first tag file” body-content=”scriptless”%>
<%@ tag body-content=”empty” %>
7.3.2、include指令
以下是项目代码片段:
includeDemoTag.tag
This tag file shows the use of whe include directive.
The first include directive demontrates 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" %>
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
<%@ taglib prefix="easy" tagdir="/WEB-INF/tags" %>
<easy:includeDemoTag></easy:includeDemoTag>
打开浏览器输入地址:
http://localhost:8089/testTag/includeDemoTagTest.jsp
7.3.3、taglib指令
利用taglib指令能够使用标签文件里的定制标签。taglib指令的语法例如以下:
<%@ taglib uri=”tagLibraryURI prefix=”tagPrefix””%>
uri属性指定一个绝对或相对的URI,用来唯一标识与这个前缀相关的标签类库描写叙述符,prefix属性定义一个字符串,它将成为用于区分某个定制动作指令的前缀。
有了taglib指令,就能够通过下面格式使用不带内容主体的定制标签:
<prefix:tagName/>
或者通过下面格式使用带有内容主体的定制标签:
<prefix:tagName>body</prefix:tagName>
7.3.4、attribute指令
attribute指令支持在标签文件里使用属性。它相当于标签类库描写叙述符中的attribute元素。语法例如以下:
<%@ attribute (attribute=”value”) %>
上述语法也能够用一种非正式的形式进行表达,如:
<%@ attribute attribute1 = “value1” attribute2=”value2” ... %>
attribute中的name属性是必须的。属性列表例如以下:
name:该标签文件可以接受的属性名称。name属性值必须在整个当前标签文件里都是唯一的。
required:表明该属性是否是必须的,它的值能够是true或false。
fragment:表明该属性是一个要通过标签处理器进行运算的部分。或在传给标签处理器之前通过容器进行运算的一个普通属性。它的值为true或者false。假设该属性要通过标签处理器进行运算,则值为true。
rtexprvalue:指定该属性值能否够在执行时通过一个scriplet表达式进行动态计算。这个值为true(默认值)或者false。
type:属性值的类型,默觉得java.lang.String
description:这个属性的描写叙述
以下是这个指令的測试:
encode.tag:
<%@ attribute name="input" 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(""") ;
}else if(c == ' '){
encodedTag.append(" ") ;
}else{
encodedTag.append(c) ;
}
}
return encodedTag.toString() ;
}
%>
<%=encodeHtmlTag(input)%>
encodeTagTest.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="easy" tagdir="/WEB-INF/tags" %>
<html>
<head>
<title>My JSP 'encodeTagTest.jsp' starting page</title>
</head>
<body>
<easy:encode input="<br />Hello CSDN" />
</body>
</html>
7.3.5、variable指令
variable指令的语法例如以下:
<%@ variable (attribute=”value”)* %>
非正式形式的表达语法例如以下:
<%@ variable attribute1=”value” attribute2=”value2” %>
variable指令的属性例如以下:
name-given:将要在调用JSP页面的脚本语言或者EL表达式中使用的变量名称。假设使用name-form-attribute。就不能再用name-given属性,反之亦然。name-given的值不能与该标签文件里的不论什么属性值同样。
name-from-attribute:该属性与name-given类似。可是它的值应该是一个属性的名称,而且它在開始进行标签调用之时提供变量名称,假设同一时候指定name-given和name-form-attribute属性,或者这两者都没有指定。那么将会产生编译错误。
alias:这是一个局部范围的属性。用于存放该变量的值。
variable-class:该变量的类型。默觉得java.lang.String
declare:表明是在调用页面中声明该变量,还是在调用之后在标签文件里声明。默认值为true。
scope:所定义脚本变量的范围,其可能值为AT_BEGIN、AT_END和NESTED(默认)
description:该变量的描写叙述
你可能会问,假设能够将处理结果直接输出到在调用jsp页面的JspWriter。那么为什么还须要variable指令呢?这是由于。仅仅将String发送到JspWriter,会导致在调用的Jsp页面丧失怎样使用该结果的灵活性。比如将server的当前如期以long格式输出。假设你还想以short格式提供server的当前日期。那么就必须另外编写一个标签文件。有两个标签文件来完毕类似功能时,会添加不必要的维护问题。
替代做法是,在标签文件里暴露两个变量:longDate和shortDate。
以下是測试代码:
varDemo.tag
<%@ tag import="java.util.Date" 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></jsp:doBody>
varDemoTest.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib tagdir="/WEB-INF/tags" prefix="easy" %>
<html>
<head>
<title>My JSP 'varDemoTest.jsp' starting page</title>
</head>
<body>
Today's date:
<easy:varDemo>
In long format: ${longDate}
<br />
In short format: ${shortDate}
</easy:varDemo>
</body>
</html>
有时候。会须要用到变量。再举个样例。
如果你须要编写一个定制动作指令。用来从数据库中获取某个指定产品标识符的产品具体信息。为此,能够用一个attribute来设置产品表示符。并用一个变量来保存每一条信息。因此。终于你会有这些变量:name、price、description、imageUrl等。
7.4、doBody
标签动作指令doBody仅仅能通过标签文件内部进行使用。
我们能够用它调用标签的主体。
doBody动作指令能够带有属性。假设须要将标签调用的结果导入到某个变量中。就能够使用这些属性。
假设使用doBody时不带属性,那么标准动作指令doBody就会将输出结果写入在所调用JSP页面的JspWriter中。
标准指令doBody的属性例如以下:
var:这是一个限域属性名称,用来保存标签主体调用的输出。
它的值保存为java.lang.String。var和varReader二者不能同一时候存在。
varReader:这是一个限域属性名称。用来保存标签主体调用的输出。
它的值保存为java.io.Reader。var和varReader二者不能同一时候存在。
scope:结果变量的范围。
以下是对于doBody的样例:
doBodyDemo.tag
<jsp:doBody var="referer" scope="session"></jsp:doBody>
main.jsp
<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>
Your referer header:${header.referer}
<br/>
<tags:doBodyDemo>
${header.referer}
</tags:doBodyDemo>
<a href="viewReferer.jsp">View</a> the referer as a session attribute.
viewReferer.jsp
The referer header of the previous page is ${sessionScope.referer}
searchEnginer.html
Please click <a href="main.jsp">here</a>
7.5、invoke
invoke标准动作指令与doBody相似,能够在标签文件里用来调用一个fragment属性。
前面说过,属性能够带有一个fragment属性,它的值为true或false。假设fragment属性值为true。那么该属性就是一个fragment属性,你能够依据须要通过标签文件对它进行多次调用。invoke也能够带有属性。invoke的属性例如以下。注意:仅仅有fragment属性是必须的。
fragment:在这个标签调用期间用于标识该fragment的名称。
var:这是一个限域属性名称,用来保存标签主体调用的输出。它的值保存为java.lang.String。var或varReader属性二者不能同一时候存在。
scope:结果变量的范围。
以下是对于invoke的样例:
invokeDemo.tag
<%@ attribute name="productDetails" fragment="true" %>
<%@ variable name-given="productName" %>
<%@ variable name-given="description" %>
<%@ variable name-given="price" %>
<%
jspContext.setAttribute("productName", "Pelesonic DVD Player") ;
jspContext.setAttribute("description", "Dolby Digital output through coaxial digital-audio jack,"+
" 500 lines horizontal resoulution-image digest viewing") ;
jspContext.setAttribute("price", "65") ;
%>
<jsp:invoke fragment="productDetails"></jsp:invoke>
invokeTest.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="easy" tagdir="/WEB-INF/tags" %>
<html>
<head>
<title>My JSP 'invokeTest.jsp' starting page</title>
</head>
<body>
<easy:invokeDemo>
<jsp:attribute name="productDetails">
<table width="220" border="1">
<tr>
<td><b>ProductName</b></td>
<td><b>${productName}</b></td>
</tr>
<tr>
<td><b>Description</b></td>
<td><b>${description}</b></td>
</tr>
<tr>
<td><b>Price</b></td>
<td><b>${price}</b></td>
</tr>
</table>
</jsp:attribute>
</easy:invokeDemo>
</body>
</html>
以下是结果截图: