jsp自定义标签封装(tld)

来源:互联网 发布:ipv6根域名中国服务器 编辑:程序博客网 时间:2024/06/05 07:51
先给个实例看看

一、首先写一个类继承TagSupport
MyTag.java
 
public class MyTag extends TagSupport{
 public String username="";
 public int doEndTag() throws JspException {
  JspWriter out = pageContext.getOut();
  try {
   out.print("<table border=\"1\">");
   out.print("<tr>");
   out.print("<td>"+username+"");
   out.print("</td>");
   out.print("</tr>");
   out.print("</table>");
   out.flush();
   //out.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
    return TagSupport.EVAL_PAGE;//<body-content>设置不为空,则必须返回 EVAL_BODY_INCLUDE
  }
 public void setUsername(String username) { //必须有该方法
  this.username = username;
 }
 
}
二、myTag_1.tld(TlD文件 放在WEB-INF下)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "web-
jsptaglibrary_1_2.dtd" >
<taglib>
 <tlib-version>tlib-version</tlib-version>
 <jsp-version>jsp-version</jsp-version>
 <short-name>myTag</short-name> <!-- 最好和下面的名字一样 -->
 <tag>
  <name>myTag</name>
  <tag-class>com.tjw.customTag.MyTag</tag-class>
  <body-content>empty</body-content>
 <!--empty表示为空不能加内容(即<input />),jsp表示内容为jsp,
tagdependent表示内容由标签去解析-->
  <attribute> <!--传入名配置属性-->
   <name>username</name> <!--必须和ShowTable.java中的username同名-->
   <required>true</required>
   <rtexprvalue>true</rtexprvalue> <!--可以使用EL-->
  </attribute>
 </tag>
</taglib>
三、jsp页面:
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="mt" uri="WEB-INF/myTag_1.tld" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  </head>
 
  <body>
    This is my JSP page. <br>
    <br>
    <mt:myTag username="hello good!" />
  </body>
</html>
四、浏览器查看源代码,显示为
  <body>
    This is my JSP page. <br>
    <br>
    <table border="1"><tr><td>hello good!</td></tr></table>
  </body>

文章一:

自定义标签的开发步骤:定义一个标签处理类;定义描述文件;根据描述文件处理标签

      定义描述文件的过程:在WEB-INF下创建一个tld文件,复制apache-tomcat-7.0.22\webapps\examples\WEB-INF\jsp2目录下的jsp2-example-taglib文件的头信息和一个<tag>标签内信息到这个事先创建好的tld文件中,并作出相应修改。

tld部分文件内容的解释:

[plain] view plain copy
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2.   
  3.    
  4.   
  5. <taglib xmlns="http://java.sun.com/xml/ns/j2ee"  
  6.   
  7.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  8.   
  9.     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"  
  10.   
  11. version="2.0">   
  12.   
  13.    
  14.   
  15. <!—-此标签库的一个简短描述-->  
  16.   
  17. <description>there are custom tags of tag</description>  
  18.   
  19. <!—-此标签库的版本,由标签开发者自行决定(必须元素)-->  
  20.   
  21.     <tlib-version>1.0</tlib-version>  
  22.   
  23. <!—-定义一个简短的名称,主要是给一些工具使用(必须元素)-->  
  24.   
  25. <short-name>tag</short-name>  
  26.   
  27. <!—-定义此标签库的uri路径,用于唯一标识该数据库,便于页面的引用-->  
  28.   
  29.     <uri>http://cn.csdn.web.tag</uri>  
  30.   
  31.     <!—-此标签库中的一个标签处理器的声明-->  
  32.   
  33. <tag>  
  34.   
  35.     <!—-该标签处理器的一个简短描述-->  
  36.   
  37. <description>view ip of client</description>  
  38.   
  39.     <!—-该标签名称(必须元素)-->  
  40.   
  41. <name>ViewIP</name>  
  42.   
  43.     <!—-该标签处理类的全限定名(必须元素)-->  
  44.   
  45. <tag-class>cn.csdn.web.tag.ViewIP</tag-class>  
  46.   
  47. <!—-指明该标签主题类型)-->  
  48.   
  49.         <body-content>empty</body-content>  
  50.   
  51.     </tag>  
  52.   
  53. </taglib>  

tld文件中要注意的事项:
    必须建立在WEB-INF目录下;

   <body-content></body-content>中指定标签体的格式有四种:

     empty:表示标签没有标签体

     scriptless:表示标签体可以包含EL表达式和JSP的动作元素,但不能包含脚本表达式

     JSP:表示标签体可以包含JSP代码

     tagdependent:表示标签体由标签本身去解析处理。若指定tagdependent,那么在标签体中所写的代码将作为纯文本原封不动地传给标签处理类,而不是将执行结果传给标签处理类

文章二

在JSP中使用标签是很平常的事情,在制作自定义标签时,通常都需要写tld文件来定义标签的各种属性,对应的java类,前缀等等。标签与tld文件紧紧相连,那么,到底应该怎么放置tld文件?在web.xml中怎么定义tld文件的位置?

以下是具体的分析

Taglib的使用:

首先是在头部申明taglib, uri必须是web.xml定义的,或者是原始tld文件定义的。

<%@ taglib prefix="c"uri="http://java.sun.com/jstl/core" %>

<%@ taglib prefix="ex"uri="/jstl-examples-taglib" %>

 

然后便可以在jsp页面中通过prefix使用相应的标签

<c:import varReader="reader"url="${filepath}">

  <ex:escapeHtmlreader="${reader}"/>

</c:import>

 

 Uri与tld文件的映射关系

JSP文件中使用的标签通常都有一个tld定义文件(标签库定义文件,主要定义标签对应的java类,标签的属性等等信息)与之对应的,web容器需要找到相应的tld文件,以tld文件中定义的内容判断标签的使用是否正确。

Web做【使用正确性】判断处理,当遇到类似【<c:import】这样的标签时,会通过prefix定位到uri,再根据uri定位到相应的tld文件,对tld文件进行解析。其中urißàtld文件的映射关系如下:

Key

(Uri)

Value

(String[] taglib_tld_location)

Taglib-URI:

(如/jstl-examples-taglib、http://java.sun.com/jstl/core等)

taglib_tld_location[0]

taglib_tld_location[1]

本文主要介绍的便是uri到tld的映射

 

Tld文件路径定义方式

如下方式1和方式2只能在2.3版本使用,Servlet2.4开始便不能在web.xml中定义taglib了。

<!DOCTYPE web-app

    PUBLIC "-//SunMicrosystems, Inc.//DTD Web Application 2.3//EN"

    "http://java.sun.com/dtd/web-app_2_3.dtd">

l  方式1:

如下所示,在web.xml中定义

    <taglib>

        <taglib-uri>/jstl-examples-taglib</taglib-uri>

        <taglib-location>/WEB-INF/lib/jstl-examples.tld</taglib-location>

</taglib>

如果这样定义的话,映射关系便如下:

/jstl-examples-taglibßà{“/WEB-INF/lib/jstl-examples.tld”,””} // taglib_tld_location[0]就足以表示tld路径,因此taglib_tld_location[1]为空。

 

l  方式2:

如下所示,在web.xml中定义

    <taglib>

        <taglib-uri>/jstl-examples-taglib</taglib-uri>

        <taglib-location>/WEB-INF/lib/jstl-examples.jar</taglib-location>

</taglib>

如果这样定义的话,映射关系便如下:

/jstl-examples-taglibßà{“/WEB-INF/lib/ jstl-examples.jar”,” META-INF/taglib.tld”}

 // taglib_tld_location[0]表示jar路径,taglib_tld_location[1]固定为META-INF/taglib.tld(也就是说,tld在jar文件中的保存路径必须是META-INF/taglib.tld,名称必须是taglib.tld)。这就是说一个jar里只能有一个tld。如果代码中不固定为taglib.tld的话,也很难处理,因为如果tld的名称可以随便定义的话,出现多个tld在jar文件中时将会导致混乱。

 

l  方式3:

不需要在web.xml中定义,只需要把tld保存在web应用能够使用的jar文件中的META-INF路径下便可。这种情况的机制是这样的:web容器会遍历当前web应用能够访问的jar文件,从jar文件中查找META-INF/xxx.tld文件,当找到一个tld文件之后,便会解析tld文件,取出<taglib>节点的<uri>值,把uri作为key值生成映射关系。

如下所示的jstl的core标签库的tld文件,便会有如下的映射关系

http://java.sun.com/jstl/coreßà{“tld文件所在的jar文件的路径”,” META-INF/xxx.tld”}//taglib_tld_location[0]表示jar路径,taglib_tld_location[1]为所搜到的tld在jar文件中的相对路径

……

<taglib>

  <tlib-version>1.0</tlib-version>

  <jsp-version>1.2</jsp-version>

  <short-name>c</short-name>

  <uri>http://java.sun.com/jstl/core</uri>

  <display-name>JSTLcore</display-name>

  <description>JSTL 1.0 corelibrary</description>

……

  <tag>

    <name>catch</name>

    <tag-class>org.apache.taglibs.standard.tag.common.core.CatchTag</tag-class>

    <body-content>JSP</body-content>

    <description>

        Catchesany Throwable that occurs in its body and optionally

        exposesit.

    </description>

    <attribute>

        <name>var</name>

        <required>false</required>

        <rtexprvalue>false</rtexprvalue>

    </attribute>

  </tag>

……

 

Ø  Tld文件的解析逻辑

以jstl为例:

Web容器遇到类似【<c:import】标签时,就会通过在头部中定义的<%@ taglib prefix="c"uri="http://java.sun.com/jstl/core" %>找到uri,再根据此uri便可以定位到taglib_tld_location。当taglib_tld_location[0]不是jar文件时,便直接使用java的FileInputStream读取tld文件;当taglib_tld_location[0]是jar文件时,则会

通过如下代码读取tld文件。

URL jarFileUrl = new URL("jar:" +location[0] + "!/");

ZipEntry jarEntry = jarFile.getEntry(location[1]);

 

Ø  总结:

Tld的定义可以不在web.xml中定义,这时需要保证tld在web应用能够访问的jar中,并且保存在jar的META-INF目录下。此时JSP直接使用tld中定义的<uri>便可;

如果在web.xml中定义tld的路径的话,可以直接指定tld文件路径,此时要保证tld不在jar包中(比如在WEB-INF目录下);也可以指定为jar文件路径,此时要保证tld在jar中且路径为META-INF/taglib.tld。

在web.xml中定义的uri优先级要高于tld文件中定义的优先级。

原创粉丝点击