极简设计

jstl

jstl

tomcat、servlet、JSP、JSTL

Tomcat版本 Servlet Jsp Jstl
6.0 2.5 2.1 1.1.x/1.2
5.5 2.4 2.0 1.1.x
5.0 2.4 2.0 1.1
4.1 2.3 1.2 1.0
3.3 2.2 1.1

即 JSTL 1.0(不支持EL) requires Servlet 2.3/jsp 1.2 /Tomcat 4

JSTL1.0和JSP1.2需要servlet2.3


<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.3 " xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   http://java.sun.com/xml/ns/j2ee/web-app_2_3 .xsd">

JSTL 1.1 requires Servlet 2.4/jsp 2.0/Tomcat 5 JSTL1.1和JSP2.0需要servlet2.4


<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">

JSTL 1.2 requires Servlet 2.2/jsp 2.1/Tomcat 6 JSTL1.2需要servlet2.5


<web-app xmlns="http://java.sun.com/xml/ns/javaee"
version="2.5"
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-app_2_5.xsd">

taglib url JSTL1.0 /META-INF/c-1_0.tld <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> JSTL1.1/1.2都是 /META-INF/c.tld <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

servlet2.4 默认支持 el表达式 servlet2.5默认禁用el,要用 <%@ page isELIgnored="false"%>

Servlet2.3中最好用JSTL1.0,如果用JSTL1.1,请加上


 <taglib>  
<taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>  
<taglib-location>/WEB-INF/c.tld</taglib-location>  
</taglib>  

把tld目录下的c.tld拷贝到/WEB-INF下

2009年之前,Jakarta Taglib项目组提供JSTL实现jar包(jstl.jar/standard.jar),此后转到tomcat小组旗下 http://tomcat.apache.org/taglibs/

JSTL的另一个实现,由glassfish提供的,最新版本也是1.2,而且看日期还是2011年的版本

so


<dependency>
    <groupId>org.apache.taglibs</groupId>
    <artifactId>taglibs-standard-spec</artifactId>
    <version>1.2.5</version>
</dependency>
<dependency>
    <groupId>org.apache.taglibs</groupId>
    <artifactId>taglibs-standard-impl</artifactId>
    <version>1.2.5</version>
</dependency>
<dependency>
    <groupId>org.apache.taglibs</groupId>
    <artifactId>taglibs-standard-jstlel</artifactId>
    <version>1.2.5</version>
</dependency>

XML tag library requires Apache Xalan 2.7.1 or later xalan-2.7.1.jar serializer-2.7.1.jar

参考 http://oldbig.iteye.com/blog/2240432 一,问题概述

jstl标准化了jsp开发,使页面更清晰 jsp取request中属性username,以前:

<%
      String username=(String)request.getAttribute("username");
      out.println(username);
%>

<%
      String username=(String)request.getAttribute("username");
%>
<%=username%>

jstl:


<c:out value="${username}"/>

${username}

可见去掉<%%>的使用后,jsp的确简洁了许多

具体使用中,有时得在jsp中借助java代码来实现 例如在jsp 中要求取出request属性信息中的用户列表userlist,列出每个用户时,如果该用户为管理员用户(假设该判断由一个工具类的静态方法来提供), 则该用户显示为红色,以前习惯的方式为:

<%
     List users=(List)request.getAttribute("userlist");
     Iterator us=users.iterator();
     while(us.hasNext()){
         User user=(User)us.next();
         booean hasAdminRole=PermissionUtil.hasRole(user,Role.ADMIN);
         String color="black";
         if(hasAdminRole){
             color="red";
         }
%>
<%=user.getName%>
<%
     }
%>

jstl实现:


<c:set var="color" value="black"/>
<c:forEach items="${userlist}" var="user">
    <c:if test="如果是管理员">
       <c:set var="color" value="red"/>
   </c:if>
   <font color="<c:out value='${color}'/>"><c:out  value="${user.name}"/></font>
</c:forEach>

基本上可以,但是问题就在于如何判断每次循环到的用户是否为管理员呢?我们知道判断方法是在一个工具类中实现的,而jstl标签中还没有可以直接调用类的方法的标签,因此仅是标签的jstl无法满足这个要求

二,解决方式

1,自定义标签:


<%@ taglib uri="/WEB-INF/MyRoleCheck.tld" prefix="role"%>
<c:set var="color" value="black"/>
<c:forEach items="${userlist}" var="user">
   <role:check user="${user.name}" role="admin">
       <c:set var="color" value="red"/>
   </role:check>
   <font color="<c:out value='${color}'/>"><c:out  value="${user.name}"/></font>
</c:forEach>

当然,上面的方式要求我们自定义的标签能够支持对el方式的解析,这实际上可以通过EvalHelper类来实现

2,联合使用jstl与java API 使用这种方式,我们需要对jstl了解的更深一些,我们知道jstl和java api(或者说是<%%>方式)是很不相同的两种书写方式,他们之间的变量有些可以很好的传递,但有些却让人摸不着头脑,例如: 1)<%%>变量在jstl中获取的例子: <% String username="zhangsan"; pageContext.setAttribute("username",username); %> <c:out value="${username}"/> 即:jsp 页面中<%%>中的变量在定义后,需要放置到pageContext属性中,才能被获取(当然也可以放置到request和session、 applicatio中,这要根据实际应用来做决定,一般只是在页面中使用的化,使用pageContext就可以了)。

2)jstl变量在<%%>中获取的例子:


<c:set var="username" value="zhangsan"/>
<%
      String username=(String)pageContext.getAttribute("username");
%>

上面为什么要在pageContext中来获取呢,因为c:set方式定义的变量默认是存放在pageContext的属性中的,当然了如果在定义是指定了作用范围,则也需要通过相应作用范围的页面对象来获取该属性,例如:


<c:set var="username" value="zhangsan"  scope="session"/>
<%
      String username=(String)session.getAttribute("username");
%>

另 外,还要主要一点,jstl中的许多操作都用到了var属性,例如c:forEach、c:import等等,这些var所代表的变量默认也是存放在 pageContext中的,当然有些标签还提供了scope属性,这也意味着其var所代表的变量会存放到scope指定的范围之中

在理解这些的基础上,再来使用联合方式解决最初的问题就相对好说多了,如下:


<c:forEach items="${userlist}" var="user">
   <%
         User user=(User)pageContext.getAttribute("user");
         booean hasAdminRole=PermissionUtil.hasRole(user,Role.ADMIN);
         String color="black";
         if(hasAdminRole){
             color="red";
         }

   %>
   <font color="<%=color%>"><c:out  value="${user.name}"/></font>
</c:forEach>

tomcat7


<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.2.1</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>javax.servlet.jsp.jstl-api</artifactId>
    <version>1.2.1</version>
</dependency>
<dependency>
    <!-- Apache JSTL implementation -->
    <groupId>org.glassfish.web</groupId>
    <artifactId>javax.servlet.jsp.jstl</artifactId>
    <version>1.2.2</version>
    <exclusions>
        <exclusion>
            <!--
            use javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api, exclude this one
            -->
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

tomcat8


<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.3.1</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>javax.servlet.jsp.jstl-api</artifactId>
    <version>1.2.1</version>
</dependency>
<dependency>
    <!-- Apache JSTL implementation -->
    <groupId>org.glassfish.web</groupId>
    <artifactId>javax.servlet.jsp.jstl</artifactId>
    <version>1.2.2</version>
    <exclusions>
        <exclusion>
            <!--
            use javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api, exclude this one
            -->
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

in java with : jstl