瘋狂

          STANDING ON THE SHOULDERS OF GIANTS
          posts - 481, comments - 486, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          web和jstl

          Posted on 2011-04-09 10:26 瘋狂 閱讀(2130) 評論(0)  編輯  收藏 所屬分類: java web

          關于taglib中tld定義的說明

          在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:escapeHtml reader="${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 "-//Sun Microsystems, 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>JSTL core</display-name>

            <description>JSTL 1.0 core library</description>

          ……

            <tag>

              <name>catch</name>

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

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

              <description>

                  Catches any Throwable that occurs in its body and optionally

                  exposes it.

              </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。

           

          以前用WSAD wizard做的,都可以在JSP頁面中解析到EL表達式,當然前提是JSP2.0的情況下。
          今天遇到了一個莫名其妙的問題。剛下載Eclipse3.3+MyEclipse6.0體驗的過程中,遇上了解析不到EL表達式的問題。經過好幾個小時的琢磨終于發現了,給大家share一下:
          問題就出在建Web Project的時候web.xml聲明上。
          web.xml聲明部分一般分為如下版本的xsd,
          web-app_2_2.xsd
          web-app_2_3.xsd
          web-app_2_4.xsd
          web-app_2_5.xsd

          更詳細的列出各版本web.xml聲明部分吧,如下:
          web-app_2_2.xsd

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/dtd/web-app_2_2.dtd">

          web-app_2_3.xsd

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

          web-app_2_4.xsd

          <?xml version="1.0" encoding="UTF-8"?>
          <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee  http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

          web-app_2_5.xsd

          <?xml version="1.0" encoding="UTF-8"?>
          <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">


          確定web.xml里的xsd版本之后一定要在JSP的聲明(<%@page %>)部分加一行,如下:
          <%@ page isELIgnored="false" %>
          這樣設為false才能解析EL表達式。
          經過各版本的test之后....
          注意!! 其中servlets 2.4(我沒記錯的話JSP 2.0出來之后的第一個版本),這個版本的isELIgnored默認設置為false。所以使用web.xml里用web-app_2_4.xsd聲明的時候在JSP頁面不用特意聲明。

          下面是官方Documention中isELIgnored Attribute的詳解:
          The isELIgnored Attribute
          • Format
          – <%@ page isELIgnored="false" %>
          – <%@ page isELIgnored="true" %>
          Purpose
          – To control whether the JSP 2.0 Expression Language
          (EL) is ignored (true) or evaluated normally (false).
          • Notes
          – If your web.xml specifies servlets 2.3 (corresponding to
          JSP 1.2) or earlier, the default is true
          • But it is still legal to change the default—you are permitted
          to use this attribute in a JSP-2.0-compliant server
          regardless of the web.xml version.
          – If your web.xml specifies servlets 2.4 (corresponding to
          JSP 2.0) or earlier, the default is false


          本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/qingkangxu/archive/2010/12/05/6057034.aspx

          主站蜘蛛池模板: 乐平市| 仁化县| 钟山县| SHOW| 独山县| 武冈市| 利川市| 红河县| 古蔺县| 霍林郭勒市| 长葛市| 岳阳县| 瑞昌市| 景宁| 葵青区| 珠海市| 休宁县| 五寨县| 贞丰县| 河源市| 肃宁县| 屯昌县| 偏关县| 丰顺县| 龙胜| 长宁区| 河南省| 巩留县| 搜索| 虹口区| 谷城县| 衡东县| 宝兴县| 盐亭县| 疏勒县| 乡城县| 屯门区| 连州市| 安远县| 林甸县| 鹿泉市|