欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

jstl自定义标签

程序员文章站 2022-06-08 18:05:38
...

自定义标签

  正常:包含起始标签,标签体,结束标签

  空标签: 没有标签体,但可包含标签属性

  嵌套标签: 自定义标签内包含其他自定义标签

如何开发自定义标签:

  * 定义需求

  * 定义标签形式

  * 编写标签处理器

  * 编写标签的描述文件tld

  * 在web.xml文件中制定tld的位置,servlet2.4,jsp2.0以上版本,不用配置此项

  * JSP页面导入和使用标签

如何开发自定义标签:

 

 * 定义需求:遍历集合  

<yxk:forEach items="${lists}" var="per">
     ${per.name }----${per.age }<br/>
</yxk:forEach>

 * 定义标签处理类,实现SimpleTag接口

public class DateTag implements SimpleTag {
                                                                                                    
     private PageContext pageContext;//上下文对象
     private JspFragment jspBody;//标签体
     private Object items;
     private String var;
                                                                                                    
     /**
      * 1 jsp引擎将调用该方法,
      *   * 将代表jsp页面的pageContext对象,传递给该方法
     */
     public void setJspContext(JspContext pc) {
          this.pageContext=(PageContext) pc;                     
     }
     /**
      * 2 jsp引擎将调用该方法,
      *   * 设置属性Items
     */
     public void setItems(Object items) {
         this.items = items;
     }
     /**
      * 2 jsp引擎将调用该方法,
      *   * 设置属性var
     */
     public void setVar(Object var) {
         this.var = var.toString();
     }
     /**
     * 3 jsp引擎将调用该方法,
     *   * 设置代表jsp页面的标签体内容传递给该方法
     */
     public void setJspBody(JspFragment jspBody) {
         this.jspBody = jspBody;
     }
     /**
     * 4 jsp引擎调用
     * 容器调用标签处理器对象的doTag 方法执行标签逻辑
     */
     public void doTag() throws JspException, IOException {
        if (items != null) {
            Iterator it = null;
            //实现list和set,父类时Collection
            if (items instanceof java.util.Collection) {
                it = ((Collection) items).iterator();
            }
                                                                              
                                                                              
            //实现数组
                                                                              
            if(items instanceof java.lang.Object[]){
                                                                                  
                List lists=Arrays.asList((Object[])items);
                it=lists.iterator();
            }
            //实现map
            if(items instanceof java.util.Map){
                Map maps=(Map)items;
                Set sets=maps.keySet();
                for(Iterator itt=sets.iterator();itt.hasNext();){
                    String keys=itt.next().toString();
                    KeyValueSet kvs=new KeyValueSet(keys, maps.get(keys));
                    System.out.println("sdf");
                    pageContext.setAttribute(var, kvs);
                    this.jspBody.invoke(null);
                }
                                                                                  
            }
            if (it != null) {
                while (it.hasNext()) {
                    Object obj = it.next();
                    pageContext.setAttribute(var, obj);
                    this.jspBody.invoke(null);
                                                                                      
                }
            }
        }
                                                                  
    } 
}

 * 建立标签和标签处理类的关联

      * 创建mytag.tld文件,放置到/WEB-INF/tld中

      * 内容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
                                                              
  <!-- 该标签库的描述 -->
  <description>myJSTL 1.0 core library</description>
  <!-- 该标签库的概述 -->
  <display-name>MyJSTL core</display-name>
  <!-- 标签库的版本 -->
  <tlib-version>1.0</tlib-version>
  <!--在jsp页面建议使用的前缀名-->
  <short-name>yxkong</short-name>
  <!--给标签库起一个唯一的名称,可以通过该名称在外部找到mytag.tld文件  -->
  <uri>http://yxkong.com/jsp/myjstl/mytag</uri>
  <!-- 配置lwq:forEach标签-->
                                                            
  <tag>
     <!-- 在jsp页面使用的标签的名称 -->
     <name>forEach</name>
     <!-- 标签处理类的完整路径 -->
     <tag-class>cn.yxk.myTag.ForEachTag</tag-class>
     <!-- 配置标签体的类型如果是 empty:表示标签体为空-->
     <!-- 表示标签体可以包含El表达式和动作元素,但不能包含jsp的脚本元素System.out.println("xxxxx")
        * scriptless:对el表达式,解析传递给标签处理类的是运行后的结果
        * tagdependent:原样输出,对el表达式不解析
      -->
     <body-content>scriptless</body-content>
     <!--配置标签体的属性-->
     <attribute>
       <!-- 配置属性的名称,该名称根标签中的属性名称一致,同时还要和标签处理类中的setItems的属性名称一致-->
       <name>items</name>
       <!-- true表示该属性是必须存在的,false:表示该属性不是必须存在的 -->
       <required>true</required>
       <!--表示运行时表达式的值(runtime expression value) true:支持运行时表单式的值  false表示不支持运行时表达式的值 -->
       <rtexprvalue>true</rtexprvalue>
     </attribute>
     <attribute>
       <name>var</name>
       <required>true</required>
       <rtexprvalue>true</rtexprvalue>
     </attribute>
  </tag>
</taglib>

  * 在jsp页面如何使用

      * 使用<%@ taglib uri="/WEB-INF/tld/mytag.tld"  prefix="yxk"%>引入

         * taglib:jsp的标准指令,用于引入标签库

         * uri:通过该地址可以找到标签库文件(mytag.tld).

            * 可以使用/WEB-INF/tld/mytag.tld

            * 使用mytag.tld的uri标签的值 http://yxkong.com/jsp/myjstl/mytag

            * prefix="yxk":使用的前缀名,其他别名,一般情况下和<short-name>lwq</short-name>一致  

         

      *  <yxk:forEach items="${lists}" var="per">

            ${per.name }----${per.age }<br/>

        </yxk:forEach>  

 

   * tld文件的存放位置,不用在web.xml文件配置.

      *  Tld 文件可以放置在 web 应用程序的 WEB-INF 目录及其子目录中

      *  不能放置在 WEB-INF 目录下的 classes 和 lib 子目录中

      *  tld 文件也可以放置在 WEB-INF\lib 目录下的 jar 包的 META-INF 目录及其子目录中

      *  查找顺序:

          * 现在WEB-INF目录下查找,如果找不到再到WEB-INF\lib的jar包中查找[自动查找]  


实现SimpleTag借口的标签处理器类的生命周期

 1 setJspContext()

    jsp引擎将调用该方法,将代表jsp页面的pageContext对象,传递给、标签处理器对象


 2 setParent

    jsp引擎将父标签处理器对象传递给当前标签处理器对象。只有存在父标签时,jsp引擎才会调用该方法


 3 set***

    设置标签属性。只有定义了属性才会调用该方法


 4 setJspBody

    若存在标签体,JSP引擎将把标签体封装成一个jspFragment对象,调用setJspBody方法将JspFragment对象传递给标签处理器对象。若标签体为空,这个方法将不会被调用


 5 doTag()

    容器调用标签处理器对象的doTag方法执行标签逻辑

 

开发自定义标签的过程

    <descripttion>标签库的描述</descripttion>
    <display-name>标签库概述</display-name>
    <tlib-version>标签库版本 --必须的</tlib-version>
    <short-name>在jsp页面中引用的前缀名  必须的</short-name>
    <uri>给标签库起一个唯一的名称,可以通过该名称在外部找到tld文件  不是必须的,放到web-inf下可以自动装载</uri>
    <tag>
       <name>在jsp页面使用的标签的名称</name>
       <tag-class>标签处理器 类的完路径  必须的</tag-class>
       <body-content>标签体的内容,设置为empty表示标签体是空的 必须的</body-content>
         表示标签体可以包含EL表达式和动作元素,但不能包含jsp的脚本元素
        |--scriptless :对EL表达式支持,解析传递给标签处理类的值是运行后的结果
|       --tagdependent:原样输出,对EL表达式等不解析
       <attribute>
         <name>配置标签属性的名称,该名称跟标签中的属性名称必须一致,而且还要和标签处理器中的名称要一致</name>
         <required>true表示该属性在标签中是必须属性,使用时不可少</required>
         <rtexprvalue>true:表示该标签的此属性支持El等表达式,false则不会编译表达式 </rtexprvalue>(runtime expresstion value 的缩写)
       </attribute>
   </tag>