学习编写标记文件(tag)上

//wrote by bGiraffe 14-10-2006
//本文章的例子下载 http://pickup.mofile.com/3643634964818862

学习编写标记文件(tag):

自定义标记的用途就是给程序员可以自定一些特定功能的标记, 以及封装代码, 达到分工, 重用性等
多种好处.

JSP规范2.0中新增了标记文件(tag file)的使用, 免除以前自定义标记必须为一个Java类, 以及必须
加上一个标记描述文件(tld)的编码难度.

以下我们来看标签文件的使用.

1. 存放:

一个标记文件以tag为後缀名, 以同一类型的检签放到同一个文件夹中组成一个标记库, 再放到
"/WEB-INF/tags/"中保存.

例如接下来我打算建立一组有关数学的标记库, 我在"/WEB-INF/tags/"下建立一个"maths"文件夹, 然
後就可以在"/WEB-INF/tags/maths/"下建立後缀名为tag的标记文件了.

现在我想先做一个数字相加的标记, 起名为"add.tag", 放到maths标记库下.

2. 语法:

标记文件其实就是一个jsp文件, 所以语法基本上跟jsp是一样的, 在第一行加上以下这个元素来告诉
服务器它是一个标记文件:

<%@ tag %>

我们还要加上一些属性来告诉服务器这个标记文件的设定:

1) body-content - 设定这个标记的主体内容类型:

A. empty
这个是一个空标记.
B. scriptless
主体可以有内容, 而jsp容器会去处理里面的jsp元素, 换句话就是可以是
文本, EL表达式, 标准动作甚至另一个自定义标记.
C. tagdependent
主体可以有内容, 而jsp容器会把它们当作纯文件处理 .

2) pageEncoding - 设定这个标记的编码

我们的add标记是个空标记, 而编码是"UTF-8", 所以加上这样的一句:

<%@ tag body-content="empty" pageEncoding="UTF-8" %>

标记中使用以下这个元素来声明属性:

<%@ attribute %>

attribute元素也有几个属性:

1) name - 这个attribute的名称.

2) required - true/false, 是否必须的.

3) rtexprvalue - true/false, 这个attribute可否使用EL表达式, 否则为纯文本.

4) type - 设定这个attribute的类型, jsp容器会把结果自动转换成这个类.

我们的add.tag有两个属性, 分别代表两个要相加的数字, x跟y, 它们都是必须的, 可以用EL表达式:

<%@ attribute name="x" required="true" rtexprvalue="true" %>
<%@ attribute name="y" required="true" rtexprvalue="true" %>

那这个标记都设定好了, 那我们应该怎样读取这些传入的属性呢? 其实很简单, 标记文件就是一个
jsp文件, 这些输入的属性值都存放在作用域中, 所以利用EL表达式就可以了:

${x + y}

这个标记文件就完成了, 以下为完整代码, 你也可以直接打开"/WEB-INF/tags/maths/add.tag":

<%--
maths标记库add标记

功能: 把传入参数相加
参数:
x, 数字1, 必须
y, 数字2, 必须
--%>

<%@ tag body-content="empty" pageEncoding="UTF-8" %>

<%-- 声明属性 --%>
<%@ attribute name="x" required="true" rtexprvalue="true" %>
<%@ attribute name="y" required="true" rtexprvalue="true" %>

<%-- 内容 --%>
${x + y}

标记文件完成了, 那我们要怎样在jsp文件中调用它呢? 首先我们导入maths标记库, 跟调用标准动作
一样使用taglib指令, 但是把url属性换成tagdir, 指定我们自定义标记库的位置, 并给它一个前缀
名, 以下我们用"maths":

<%@ taglib tagdir="/WEB-INF/tags/maths/" prefix="maths" %>

然後我们就可以调用标准动作一样去使用它啦, 当然必须的属性一定要有, 不然会报错:

<maths:add x="10" y="10"/>

以下为调用add标记的jsp页的完整代码, 同样的你可以直接打开"/add.jsp":

<%-- maths标记库add标记的演试 --%>
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<%-- 调用自定义标记库maths --%>
<%@ taglib tagdir="/WEB-INF/tags/maths" prefix="maths" %>

<html>
<head>
<title>Maths标记库add标记演试</title>
</head>
<body>
结果:<br/>
<%-- 使用add标记 --%>
<maths:add x="10" y="10"/>
</body>
</html>

相信大家都了解基本工作原理了吧? 你可以把标记文件看作一个jsp页面, 你可以对它传入一些参数,
调用它的面页就像包含它一样, 所以你可以标记文件打上一句"HelloWorld", 一段html代码, 甚至包
含其他的动作, 调用它的面页就会显示, 大家可以打开"/helloworld.jsp"看一下, 它调用了别一个
标记库others里面的helloworld标记.

add标记是一个空标记, 我们学过body-content="scriptless", 那我们应该怎样去处理标记主体的数
据呢? 我们来新增一个新的标记库, 叫string, 再增加一个标记文件"show.tag", 同样的加上tab指
令告诉服务器这个是一个标记文件, 这一次body-content属性改为scriptless:

<%@ tag body-content="scriptless" pageEncoding="UTF-8" %>

然後我们加入一个标准动作:

<jsp:doBody>

它的用途是读入标记的主体内容, 当没有指定要保存到的变量时, 它把内容直接输出到调用的页面上.

我们写一个"/show.jsp"来简单调用这个show标记:

<%-- string标记库show标记的演试 --%>
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<%-- 调用自定义标记库string --%>
<%@ taglib tagdir="/WEB-INF/tags/string" prefix="string" %>

<html>
<head>
<title>string标记库trim标记演试</title>
</head>
<body>
<%-- 使用show标记 --%>
<string:show>
这个是标记的主体内容
</string:show>
</body>
</html>

<jsp:doBody>有三个属性:

1) var - 当指定这个变量, 读取的主体内容就会以String保存这个变量内, 不会直接输出页
面.

2) varReader - 用途跟var一样, 但是保存的不是一个String, 而是一个java.io.Reader.

3) scope - 变量保存到的作用域, 包括: page, request, session, application, 默认为
page.

接下来我们扩充string标记库, 加入一个新的标记"trim.tag", 同样的加入tag指令, 设定
body-content为scriptless代表它可以有主体内容, 因为我们会使用到核心标记库, 所以加上taglib
指令导入核心标记库, 并加入jsp:doBody指令读取主体内容并保存到变量body中:

<%@ tag body-content="scriptless" pageEncoding="UTF-8" %>

<%-- 导入核心标记库 --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<%-- 把主体内容保存到body变量中, 没有指定作用域下, 保存在page --%>
<jsp:doBody var="body"/>

我们获得一个主体内容的字符串了, 那可以编写一段代码来把字符串中的空白去掉, 我们可以利用核
心标记库的一个标记forTokens来把字符串跟据空白来分割, 再输出就可以达到这个效果了, 以下给出
这个标记的完整代码, 大家也可以直接打开"/WEB-INF/tags/string/trim.tag":

<%--
string标记库trim标记

功能: 把标记主体的内文中的空白去掉
--%>

<%@ tag body-content="scriptless" pageEncoding="UTF-8" %>

<%-- 导入核心标记库 --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<%-- 把主体内容保存到body变量中, 没有指定作用域下, 保存在page --%>
<jsp:doBody var="body"/>

<%-- 实现把主体字符串的空白去掉 --%>
<c:forTokens var="char" items="${body}" delims=" ">${char}</c:forTokens>

这里有一个要注意的, 最後一行必须要这样写, 什么意思? 很多人(包括我)可能会这样写:

<c:forTokens var="char" items="${body}" delims=" ">
${char}
</c:forTokens>

这个是好习惯, 代码看上去整齐多了, 但是jsp容器会把换行换成一个空白...哈哈, 不懂的自己试一
下吧^^

这个演试可以看到标记文件不单没有以前标记处理类加上一个tld来得那么麻烦, 而且在一个标记文
件中, 我们可以再导入另一个标记库来扩充功能, 实在是非常方便.

相信大家都对标记文件的基本应用都有一定的了解了, 下面我们来看标记文件的其他功能.

如果我们想建立一些标记文件供网页人员使用, 而且这个标记文件支持所有html元素的属性, 那你可
能立刻就想到, 我们必须为每一个可能出现的html标记属性建立一个属性标记, 那是多费时的工作,
所以我们可以在tab指令中加上dynamic-attributes这个属性, 表示这个标记可以容许任何的属性值
出现, jsp容器会自动把所有未声明的属性保存到一个以你给出的值为命名的Map集合中, 而这个集合
保存在page作用域中. 我们来新建一个标记文件到others标记库中, 并加上以下代码行:

<%@ tag body-content="empty" pageEncoding="UTF-8"
dynamic-attributes="attributesList" %>

当调用这个标记时, 所有未被声明的属性都会保存到"attributesList"这个Map集合中, 我们可以用
核心标记库的forEach把它们列出, 以下为完整代码, 你也可以直接打开"/WEB-INF/tags/others/
showAttributes.tag":

 <%--
others标记库showAttributes标记

功能: 读取dynamic-attributes所保存的属性集合, 输出到调用的页面上.
--%>
<%@ tag body-content="empty" pageEncoding="UTF-8"
dynamic-attributes="attributesList" %>
<%-- 导入核心标记库 --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<%-- 输出所有属性 --%>
<p>本标记包含了以下的动态属性</p>
<%-- 使用forEach遍历"attributesList"集合并输出到调用页面 --%>
<c:forEach var="item" items="${attributesList}" varStatus="i">
<p>${i.index + 1}. ${item.key}: ${item.value}</p>
</c:forEach>

另外编写一个jsp页面调用showAttributes标记, 以下为完整代码, 你也可以直接打开
"/showAttributes.jsp":

 <%-- others标记库showAttributes标记的演试 --%>
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<%-- 调用自定义标记库others --%>
<%@ taglib tagdir="/WEB-INF/tags/others/" prefix="others" %>

<html>
<head>
<title>others标记库showAttributes标记演试</title>
</head>
<body>
<others:showAttributes param1="hello" param2="on9" color="red"/>
</body>
</html>

(文转 - 学习编写标记文件(tag)下)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值