关闭

JSP标签工作原理

4204人阅读 评论(0) 收藏 举报
最近在做chronicles的java项目。发现自己java web相关各种技术都比较稀松。于是给自己列了个列表,把不会的,需要加强的东西都写上去,再一点一点看。然后把学习的成果做些许记录。本文主要讲JSP标签的工作原理。首先看一个JSP文件:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 <%@ taglib uri = "http://java.sun.com/jsp/jstl/core"; prefix = "c"%>
 <%@ taglib prefix = "fn" uri = "http://java.sun.com/jsp/jstl/functions"%>
 
  <div id="ajax_wrapper">
 
     <c:if test="${fn:length(story_view_models) == 52}">
         <div id="swap_story_message">You already have 52 stories, so we will be swapping stories.</div>
     </c:if>
     <span id="${id_for_tip}">Drag the story here to add to the 52 week list...</span>
 
         <div id="approved_stories_container">
             <c:forEach items="${story_view_models}" var="model">
                 <div><span>${model.storyTruncatedTitle}</span><input type="hidden" value="${model.id}"/></div>
             </c:forEach>
         </div>
         <div id="numbering_for_approved_stories_container">
         </div>
  </div>
 
形如上面的jsp代码在第2,3行使用taglib标签引入了一些标签库,并分别定义了他们的前缀为c和fn。然后就可以使用c:forEach等标签写嵌入式的脚本了。但是这写标签是怎么工作的呢。在Intellij中使用command+B到了这些标签的定义文件,发现是一个tld文件,如下:
 
<?xml version="1.0" encoding="UTF-8" ?>
 <taglib xmlns="http://java.sun.com/xml/ns/j2ee";
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd";
     version="2.0">
    
   <description>JSTL 1.1 core library</description>
   <display-name>JSTL core</display-name>
   <tlib-version>1.1</tlib-version>
   <short-name>c</short-name>
   <uri>http://java.sun.com/jsp/jstl/core</uri>;
 
   <validator>
     <description>
         Provides core validation features for JSTL tags.
     </description>
     <validator-class>
         org.apache.taglibs.standard.tlv.JstlCoreTLV
     </validator-class>
   </validator>
 
   <tag>
     <description>
      Simple conditional tag that establishes a context for
      mutually exclusive conditional operations, marked by
      :when and otherwise.
     </description>
     <name>choose</name>
     <tag-class>org.apache.taglibs.standard.tag.common.core.ChooseTag</tag-class>
     <body-content>JSP</body-content>
   </tag>
 ................
 </taglib>

这里只粘了一个标签,即choose的定义上来,可以看到除了名字和描述之外,每个标签都对应了一个java类。当你这些标签所起的作用也就在这些类中定义了。具体这些java代码是如何写的可以参看此链接。因此自己也可以写一些自定义的标签库,如果有必要。所以一个jar包+一个tld文件就定义了一个标签库。
  上面提到了jsp文件中通过下面的代码引入taglib:
  <%@ taglib prefix = "fn" uri = "http://java.sun.com/jsp/jstl/functions"%>
  即通过uri来定位tld文件,可是这样的一个打到浏览器就会转向到oracle网站而且什么标签信息都获得不到的的url怎么就能够帮助我么找到tld文件呢?答案是在web.xml中进行配置。通常会在web.xml中有一个taglib的定义。如下:
 
<taglib>
   <taglib-uri>
     http://www.example.com/taglib
   </taglib-uri>
   <taglib-location>
     /taglib.tld
 
   </taglib-location>
 </taglib>

这就相当于给这个有意义的硬盘路径“/taglib.tld”了一个别名,也就是那个看似url的uri。然后就可以在jsp中引用了。但是我看chronicles的代码是,发现web.xml中并没有这样的定义。如是甚是纳闷。今天找了一天终于找到了答案。回到上面的tld文件,可以看到这样一行:

 

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

  这个tld文件是包含在一个叫做standard.jar的文件中的,该jar包放到了web/lib下,也就是放到了classpath下面。打开jar文件发现有两个文件夹:org, META-INF。第一个当然就是package名了,在第二个文件里包含了一大堆tld文件。每个tld都有uri这个标签来指定一个uri。于是可以大概猜测,jsp文件扫描classpat下的所有META-INF文件夹找里面的tld文件,如果遇到uri匹配的就指定该文件。然后做了个实验,把standard.jar解压,改变里面的uri标签,比如对于该例,把 http://java.sun.com/jsp/jstl/core 改成 http://java.sun.com/jsp/jstl/cor 。然后再打包替换原来的文件。再到intellij里面看jsp文件里引用taglib的那些代码都红了,也就是说找不到了。再把引用的那个uri变成跟我在jar包里修改的一样,即http://java.sun.com/jsp/jstl/cor,就ok了。

  再做两个令人发指的实验,把tld文件拷出来,分别放到和META-INF平级的目录下和org目录下,竟然也都能找到。看到它搜索的范围还真不小。所以结论是jsp会在所有的classpath及其所有子目录下进行去搜索。那么classpath下有很多jar包的时候扫描会不会特别慢,或者有一些索引缓存机制吧。


1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:71764次
    • 积分:751
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:19篇
    • 译文:0篇
    • 评论:2条
    最新评论