接下来我们看一个属性的扩展功能 - 属性片段(attribute fragment), 先解译什么是片段, 大家可以
把片段看作一段jsp代码, JSP规范中所谓的jsp fragment, 例如我们之前使用了jsp:doBody读取的主
体内容就是一个片段. 我们可以将一段巳命名的片段(named fragment)作为一个标记的属性使用, 并
而在标记中多次或一次调用这个传入的片段. 要调用这个片段, 我们使用另一个标淮动作:
<jsp:invoke/>
它是一个空标记, 有以下的属性:
1) fragment - 要调用的片段名.
2) var - 给出变量名, 把片段经过jsp容器计算过之後的结果作为字符串保存.
3) varReader - 同上, 不过将结果作为一个java.io.Reader保存.
4) scope - 作用域= =, 有var就有它, 不多说了, 默认page.
当然, 叫做属性片段, 我们必须告诉jsp容器标记中那些标记属性的内容会是片段而不是静态文本. 我
们可以在属性元素上加上fragment="true"这个属性:
<%@ attribute name="name" fragment="true" %>
接下来我们再编写一个标记来演试一下属性片段的应用, 我们在others标记库中新增一个"invoke"
标记, 加上tag指令, 建立两个属性fragment1跟fragment2, 用来接收两个属性片段, 以下给出完整
代码, 大家也可以直接打开"/WEB-INF/tags/others/invoke.tag":
<%--
others标记库invoke标记
功能: 演试属性片段
--%>
<%@ tag body-content="scriptless" pageEncoding="UTF-8" %>
<%@ attribute name="fragment1" fragment="true" %>
<%@ attribute name="fragment2" fragment="true" %>
<%-- 调用标准动作jsp:invoke显示读取的属性片段 --%>
<p style="font-size:24px; font-weight:bold">这里输出属性片段一的计算结果:</p>
<jsp:invoke fragment="fragment1"/>
<p style="font-size:24px; font-weight:bold">这里输出属性片段二的计算结果:</p>
<jsp:invoke fragment="fragment2"/>
<%-- 调用标准动作jsp:doBody显示读取的主体内容 --%>
<p style="font-size:24px; font-weight:bold">这里输出主体内容:</p>
<jsp:doBody/>
上面可以看到我们调用了两次<jsp:invoke fragment="xxx"/>, 大家可以把它看作一个占位符, 它的
位置就是读取的属性片段的计算结果. 最後我们再一次调用<jsp:doBody/>来读取主体内容.
不懂? 没关系, 下面我们先把调用页面"invoke.jsp"建立好, 细心观察浏览器出来的效果, 大家就可
以了解为什么我会说把<jsp:invoke/>看作一个占位符, 其实<jsp:doBody/>也是同一个工作原理, 下
面给出"invoke.jsp"的完整代码, 同样大家可以直接打开"/invoke.jsp":
<%-- others标记库invoke标记的演试 --%>
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<%-- 调用自定义标记库others --%>
<%@ taglib tagdir="/WEB-INF/tags/others" prefix="others" %>
<%-- 调用自定义标记库string --%>
<%@ taglib tagdir="/WEB-INF/tags/string" prefix="string" %>
<html>
<head>
<title>others标记库invoke标记演试</title>
</head>
<body>
<%-- 使用invoke标记 --%>
<others:invoke>
<jsp:attribute name="fragment1"> <%-- 第一个片段我们引用helloworld标记 --%>
<others:helloworld/>
</jsp:attribute>
<jsp:attribute name="fragment2"> <%-- 第二个片段我们引用trim标记 --%>
<string:trim>
I am a boy!
</string:trim>
</jsp:attribute>
<jsp:body> <%-- 这里就是主体内容 --%>
这里就是<font color="red" size="25">主体内容</font>啦
</jsp:body>
</others:invoke>
</body>
</html>
(上面代码的排版有点乱, 注释本来是自己开新行的, 但是属性之间如果插入注释, 服务器会报错= =)
这个jsp页面包含我们今天所建立的另外两个标记"helloworld"跟"trim", 它们分别就是两个属性片段
的内容, 另外大家会看到<jsp:body>...</jsp:body>这个没介绍过的标准动作, 因为一个标记的主体
如果巳经包含了<jsp:attribute/>元素的话, 主体的内容就必须放到<jsp:body/>之内, jsp容器才可
正常的分别到哪些是属性, 哪个是主体, 所以以下的语法是不容许的:
<others:invoke>
<jsp:attribute name="fragment1">
属性一的内容
</jsp:attribute>
<jsp:attribute name="fragment2">
属性二的内容
</jsp:attribute>
<p>这里是主体内容...</p>
</others:invoke>
下来留一个小测试给大家, 打开"/invoke.jsp", 在<jsp:body/>标记内加上这一段代码:
${"a" == "a"}
重载"/invoke.jsp", 大家会发现在网页的末尾, 出现了"true"一字, 然後我们来开"/WEB/INF/
tags/others/invoke.tag", 把tag指令中的body-content属性改为"tagdependent", 重载
"/invoke.jsp"看有什么不一样?
接下来这个会是个难点, 这个部份希望大家可以返覆多看几遍, 试著修改一下例题来了解一下参数不
同会产生什么不一样的结果.
我们一直的工作流程都是, 一个jsp页面调用一个自定义的标记, 给它一些属性, 我们在标记里读取它
们, 然後处理代码, 返回给jsp容器, jsp容器计算结果後给jsp页面输出静态的文本, 那我们可不可以
在处理代码後, 把结果以变量的形式返回呢? 就好像我们写一个有返回值的函数一样? 可能大家会想
想我们有<c:set/>这个声明/赋值的标准动作, 但是想一下, 标记文件跟jsp页面是两个不同的page作
用域, 我们如果要传递变量的话就只有把变量放在session/application中了, 那不是很麻烦? 万一我
在jsp接收变量後没有把这个变量的内存空间释放掉, 那服务器有10GB内存也不够用了, 所以JSP规范
中提供了一个指令:
<%@ variable %>
它可以让我们在标记文件中的声明一个输出变量, 让jsp页面读取, 它有以下的属性:
1) name-given - 给这个变量取名.
2) name-from-attribute - 这个变量名由一个属性来决定(跟name-given只可选一).
3) alias - 给输出变量取别名(配合name-from-attribute使用).
4) variable-class - 给出输出变量类型, jsp容器会自动转换, 如果没指定为String.
5) scope - 输出变量在jsp页面上的更新模式, 可取值为: AT_BEGIN/AT_END/NESTED, 默认
为"NESTED".
相信第1,4属性大家都看懂, 第2,3属性我们在下一个例子中再说明, 我们来说明一下scope属性.
scope的3个可取值代表什么意思呢?
1) AT_BEGIN - 输出变量在标记文件的<jsp:doBody/>/<jsp:invoke/>之前及标记文件执行结
束後更新输出变量的值.
2) AT_END - 输出变量只有在标记文件执行结束後更新输出变量的值.
3) NESTED - 输出变量在标记文件的<jsp:doBody/>/<jsp:invoke/>之前更新输出变量的值,
在标记文件结束後, 将会把输出变量还原到在调用标记前的值
不懂? 我也搞了4个小时, 返覆的试验才清楚这三个取值有什么不一样. 现在不了解没有关系, 它们关
系到在标记文件中使用到<jsp:doBody/>/<jsp:invoke/>时, 其他的代码在这些动作之前之後的不同,
我们现在只需要记得一个不同就好了. 如果你需要把输出变量输出到jsp页面上(= =不然呢?), 就用
"AT_BEGIN", 如果你只需要在标记执行中在jsp页面读取到输出变量, 那就用"NESTED".
可能大家还是会搞混了, 我不就是为了输出一个变量到jsp页面吗? 你给我一个"NESTED"干吗? 其实输
出变量还有一个用途, 就是让标记文件可以把变量传到另一个标记文件上. 如果我的标记文体主体内
容是另一个标记, 我想把值传给它而巳, 并没有需要传到jsp页面的作用域上时, "NESTED"就有用了,
因为还原的意思是, 如果调用的jsp页面本来就没有声明这个输出变量, 那就代表输出变量只有在标记
主体执行时出现过, 结束後它就卸载了.
下面我们就来看一个例子吧(还是不懂? 就只用"AT_BEGIN"吧, 管它还不还原), 以下建立了一个新的
标记文件"variable.tag"在others标记库中, 同样的加入tag指令, 导入核心标记库(?), 以下给出完
整代码, 大家也可以直接打开"/WEB-INF/tags/others/variable.tag":
<%--
others标记库variable标记
功能: 演试variable指令输出变量的功能
--%>
<%@ tag body-content="empty" pageEncoding="UTF-8" %>
<%-- 导入核心标记库 --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%-- 声明一个输出变量, 取名为"v" --%>
<%@ variable name-given="v" scope="AT_BEGIN" %>
<%-- 对输出变量赋值 --%>
<c:set var="v" value="这个就是标记文件的输出的内容"/>
为什么要使用要<c:set/>动作呢? 因为variable指令只是声明了一个变量, 我们还需要给它赋值, 下
面同样我们再建立一个"/variable.jsp", 看看jsp页面是如何读取到这个变量, 以下给出完整代码,
大家也可以直接打开"/variable.jsp":
<%-- others标记库variable标记的演试 --%>
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<%-- 导入others标记库 --%>
<%@ taglib tagdir="/WEB-INF/tags/others" prefix="others" %>
<html>
<head>
<title>others标记库variable标记演试</title>
</head>
<body>
<%-- 调用variable标记并显示 --%>
<others:variable/>
输出变量v: ${v}
</body>
</html>
有了variable指令, 我们就可以把一个标记文件处理後的结果, 放到输出变量中, 再给它指定一个类
型, 作为另一个标记文件的属性传递, 是不是很方便呢?
但是问题来了, 这个输出变量的取名是标记文件定义的, 如果调用它的页面也有这个变量那怎办? 所
以我们下面来了解一下variable指令上"name-from-attribute"跟"alias"这两个属性, 怎样可以达成
"取别名"的效果.
我们来新建一个标记文件"alias"在"others"标记库中, 同样加入tag指令, 导入核心标记库, 然後我
声明一个属性, 它的作用就是用来存放输出变量的取名, 让调用页面可以传入一个字符值来决定输出
变量的取名, 然後我们使用variable指令:
<%@ variable name-from-attribute="output" alias="v" scope="AT_END" %>
"name-from-attribute"属性告诉jsp容器这个输出变量的取名为那个属性的值, 而"alias"属性就为
这个输出变量取一个别名, 以便在标记里使用这个变量, 以下给出完整代码, 大家也可以直接打开
"/WEB-INF/tags/others/alias.tag":
<%--
others标记库alias标记
功能: 演试variable指令的取别名功能
--%>
<%@ tag body-content="empty" pageEncoding="UTF-8" %>
<%-- 导入核心标记库 --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%-- 存放输出变量的名称, 记得这个属性必须为静态文本及必须的 --%>
<%@ attribute name="output" required="true" rtexprvalue="false" %>
<%-- 声明输出变量, 在标记文件中使用别名为"v", 而在调用页面上的名称则
由属性output决定 --%>
<%@ variable name-from-attribute="output" alias="v" scope="AT_END" %>
<%-- 为输出变量赋值 --%>
<c:set var="v" value="<p>这个就是标记文件的输出的内容</p>"/>
同样的, 我们建立一个"/alias.jsp"来演试一下, 以下给出完整代码, 大家也可以直接打开
"/variable.jsp":
<%-- others标记库alias标记的演试 --%>
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<%-- 导入others标记库 --%>
<%@ taglib tagdir="/WEB-INF/tags/others" prefix="others" %>
<html>
<head>
<title>others标记库alias标记的演试</title>
</head>
<body>
<%-- 调用alias标记, 对output属性赋值就可以自定义输出变量名 --%>
<others:alias output="super"/>
${super}
<%-- 试一下用别的名称 --%>
<others:alias output="haha"/>
${haha}
</body>
</html>
使用了"name-from-attribute"就可以避免命名冲突了, 记得存放输出变量取名的属性必须把
"rtexprvalue"设为假, 不然服务器也会报错的.
以上就是JSP规范2.0中新增的标记文件的语法介绍了^^
3. 打包
今天计一下我们都创建了8个自定义动作, 如果我们想要跟人家分享我的作品, 或者要去第三方部署的
话, 那就麻烦了, 所以以下我们学习怎样去把我们的标记库打包.
第一步, 我们先改变一下文件结构, 在网站根目录下, 创建一个"META-INF"文件夹, 然後把"WEB-INF"
里面的"tags"文件夹复制过去, 形成以下文件结构:
网站根目录/
META-INF/
tags/
maths/
...tag文件...
others/
...tag文件...
string/
...tag文件...
WEB-INF/
...tag文件夹...
...jsp文件...
我们先打包string标记库, 所以把"maths"跟"others"文件夹删除, 然後我们需要创建一个tld标签描
述文件(对, 又是它, XML又来了)在"META-INF"下, 复制下面的内容到文件开始:
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLScheme-instance"
xsi:schemeLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/sml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<!-- 标记库版本 -->
<tlib-version>1.0</tlib-version>
<!-- 命名空间前缀 -->
<short-name>string</short-name>
<!-- 文件夹名 -->
<uri>string</uri>
<!-- 包含的标记 -->
<tag-file>
<!-- 标记名 -->
<name>show</name>
<!-- 路径 -->
<path>/META-INF/tags/string/show.tag</path>
</tag-file>
<tag-file>
<name>trim</name>
<path>/META-INF/tags/string/trim.tag</path>
</tag-file>
</taglib>
taglib元素的一大串属性不用管它, 这个不是我们的讨论范围, 以後要写tld文件就复制过去就对了,
版本跟命名空间前缀也可以不管, 那个是给设计工具使用的, 没什么影响, uri元素必须为标记库的
文件夹名, 之後的tag-file元素声明了这个标签库里面有什么标记, 语法为:
...
<tag-file>
<name>标记名</name>
<path>相对路径</path>
</tag-file>
...
完成後打开"命令提示符", 转到网站的根目录, 输入下面的命令:
jar cvf string.jar META-INF
完成後大家就会看到根目录下新增了一个jar文件"string.jar", 把它放到"/WEB-INF/lib"之下就OK
了. 那我们再新建一个jsp页面来调用这个巳经打包好的标记库吧, 以下为"jar.jsp"的完整代码,
同样大家可以直接打开"/jar.jsp":
<%-- 使用jar文件导入标记库的演试 --%>
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<%-- 导入string标记库包 --%>
<%@ taglib uri="string" prefix="string" %>
<html>
<head>
<title>使用jar文件导入标记库的演试</title>
</head>
<body>
<%-- 调用trim标记 --%>
<string:trim>
Please trim me!
</string:trim>
</body>
</html>
看到我们这一次taglib指令不再使用tagdir属性了, 直接用uri属性.
以上就是打包的全部讲解^^
P.S. 写在最後
因为开始要编写毕业的项目, 我发现班上有很多同学都没有能真正的掌握自定义标记的用法, 所以才
试著编写一篇讲解标记文件的文章, 顺便也可以放到BLOG上, 没想到一写就写了六百多行@"@. 但是
过程是非常愉快的, 写到一些知识点上发生自己也没搞清楚, 就跑去翻翻资料, 看看文献, 对自己本
身的能力也加强了好多, 毕竟我也是一个初学者.
希望这篇文章可以帮忙大家在标记文件的学习, 另外有很多的专业名词的翻译可能会跟大家认识有出
入, 希望大家见谅^^, 如果有其他问题可以在我的BLOG上留言, 我会尽可能的帮忙的, 谢谢.
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/bGiraffe/archive/2007/06/23/1663467.aspx
分享到:
相关推荐
自己花钱在豆丁上买的文档,确实很难找的文档。介绍tag标签的
4. **在Web应用中部署标记库**:将.tld文件放在WEB-INF目录下的tags或WEB-INF/lib目录下,取决于TLD的位置。 5. **在JSP页面中使用标签**:通过指令引入标记库,并在页面中使用定义的标签。 标记库的一个典型应用是...
这篇博客文章“将定制标签库开发为标记文件”深入探讨了如何创建自己的标签库,并将其转化为标记文件,以便在JSP页面中方便地使用。以下是对这一主题的详细阐述: 首先,我们来理解什么是自定义标签库。在Java Web...
总的来说,这个项目提供了一个在MFC环境下处理图像标记的解决方案,对于理解和实践Windows GUI应用程序开发以及图像处理技术具有一定的学习价值。通过深入研究这些代码,开发者可以学习到如何在C++环境中实现图像...
通过编写简单的测试代码,调用apriltag的API进行标记检测,以验证安装是否成功。 在实际应用中,apriltag的API包括图像读取、标记检测、位置计算等。例如,你可以使用` apriltag_family_load()`加载特定的标记类型...
《VC2010的拼图(允许TAG标记)》是一款专门为儿童设计的拼图游戏,采用Microsoft Visual C++ 2010编程环境开发,它融入了创新的"TAG"(Tag Group)功能,使得游戏体验更加独特。在这款游戏中,"TAG"功能允许将一组...
灵活掌握在Tag标记中使用标记体 编写一个JSP 页面:putImage.jsp和一个Tag文件Image.tag。JSP页面通过调用Tag文件来显示若干幅图像,通过使用标记体将显示图像的HTML标记传递给被调用的Tag文件。
1. **编写TLD文件**:例如,我们创建一个名为`mytag.tld`的TLD文件,其中包含自定义标记的定义。在这个文件中,我们需要指定标记的名字、类名、属性、以及可能的事件处理方法等。 ```xml <tlib-version>1.0 ...
实验要求编写4个JSP页面giveContent.jsp,writeContent.jsp,lookContent.jsp,readContent.jsp,以及两个Tag文件Write.tag和Read.tag。 三、giveContent.jsp页面 giveContent.jsp页面提供一个表单,要求该表单提供一...
要开发一个自定义标签,开发者首先需要编写一个标签文件,通常这个文件扩展名为`.tag`。在这个文件中,开发者可以定义标签的名称、属性以及标签体的输出内容。然后,需要在JSP页面中注册这个标签文件,并像使用其他...
为了提高工作效率,可以利用Python编写脚本来自动检查这些特殊标记词是否与文件名中的一致。 #### 1.2 实现原理 该功能主要通过以下步骤实现: - **读取Word文档**:使用Python第三方库`python-docx`来读取Word文档...
2. **编写标记处理类**:接着,创建标记处理类,例如`MyTagHandler.java`,该类需要实现`javax.servlet.jsp.tagext.Tag`接口或者其子接口。在这个类中,我们可以定义处理逻辑,如`doStartTag()`和`doEndTag()`方法。...
NBT, python 文件格式的解析器/编写器,它是RegionFile的容器 这是一个基于Persson规范的命名二进制标记解析器。spec:"NBT ( 名为二进制标记) ) 是基于标签的二进制格式,旨在携带大量的二进制数据和更小数量的额外...
首先,智能标记(Smart Tag)是一种常见于许多开发工具,如Visual Studio中的特性,它允许开发者快速访问和执行与特定控件相关的常见任务。例如,可以使用智能标记来配置控件属性、添加事件处理程序或进行其他定制...
这可能涉及到逐行读取文件,识别分隔符,或者解析特定的标记和结束标记。 7. **调试和测试**:在编写代码后,使用Perl的内建调试器或简单的print语句进行调试是常见的做法。同时,编写测试用例以确保代码正确地处理...
4. 错误处理:考虑到文件可能没有ID3标签,或者标签格式不正确,需要编写合适的错误处理代码。 在实际应用中,了解如何读取和操作ID3标签对于开发音乐播放器、音乐库管理软件等至关重要。通过解析这些标签,程序...
一个标签库由一组相关的自定义标记组成,定义在一个XML文件(TLD,Tag Library Descriptor)中。TLD文件描述了每个标记的属性、行为和关联的Java类。当JSP容器遇到自定义标记时,会根据TLD找到对应的Java类并执行...
本项目提供的"flv文件格式分析器源码"是一个用C++编写的开源工具,它可以帮助开发者深入理解FLV文件的内部结构,进行解析和分析。 FLV文件格式主要由以下几部分组成: 1. **文件头**:文件头包含文件标识符、文件...