一、关于JSTL和EL:
什么是JSTL?
JSTL( JSP Standard Tag Library)是JSP标准 标签库,由apache实现。
什么是EL?
EL(Expression Language)表达式语言。
两者关系?
JSTL在赋值时会大量用到EL表达式。可以简单理解成,EL只是JSTL中的一部分。
作用:
简化jsp页的书写;削弱jsp中调用servlet的java代码,便于分层控制。只要是jsp能够完成的功能使用JSTL和EL表达式都可以完成。包括从和Servlet的数据交互、操作XML、格式化数据显示以及样式显示(控制表格的偶数行使用不同的颜色显示等)、Request中读取数据、控制循环(数组、Map等)、支持函数处理(trim、substring、join等)、还可以自定义函数等、操作数据库(违背分层原则,一般不这么使用)。
二、EL表达式:
如果只是使用EL表达式,不需要引入任何jar包,只要jsp/servlet容器实现了J2EE1.4/servlet2.4、JSP2.0规范就可以。但是它的功能有限,如:针对于空,给出默认的输出,迭代循环数组元素等是无法实现的。对于JSTL,这些都是没有问题的,但需要进行引入和说明。
语法:${scope} scope(applicatioin/session/servlet等)
内置对象:pageScope、reqeustScope、sessionScope、applicationScope
默认搜索范围:pageScope——applicationScope
指定搜索方式:${requestScope.hello}
在jsp中,很少直接传字串,一般传的是对象,且对象中还包含有其他对象,无需引入包,要求对象都需要有get方法,在jsp中获取数据的时候,直接点出get后面的那一部分,不区分大小写。
EL隐含对象:
param:针对request.getParameter("itemNoOrName")使用这个内置对象取得数值,itemNoOrName=${param.itemNoOrName}
如果request.setAttribute("pageModel", pageModel);则直接使用EL表达式取数据。
需要注意点是:EL表达式不能取出使用常量定义的变量。
三、JSTL:
关于JSTL,不做过多的说明,jsp界面中的java代码,使用JSTL都可以替代,而且更加简洁,负责前台的人甚至可以不需要熟悉java代码。
四、使用:
演示通过使用jstl和el和核心库的使用:获取并显示用户信息。
1、引入jar包:
如果要使用JSTL,而不仅仅是EL,需要引入jstl.jar和standard.jar两个包。这里也提供下载连接。
2、定义java实体类:
这里使用一个User类和一个Group类,一个用户属于某个Group,就是两个普通的实体类,二者之间有一个关联,代码比较简单,就不贴了。
3、编写Servlet类:
package com.bjpowernode.jstl; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 核心库,测试一些字串、数组、map、list、空、循环等基础的应用 * @author LiMin * */ public class jstlCoreServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //普通字串 request.setAttribute("hello", "Hello World"); //带有html样式的文本 request.setAttribute("welcome","<font color='red'>欢迎来到这个世界!</font>"); //set User u = new User(); request.setAttribute("u", u); //条件控制标签 request.setAttribute("v1", 10); request.setAttribute("v2", 20); //空 request.setAttribute("userList", new ArrayList()); //结构 Group group = new Group(); group.setName("信息技术提高班第八期"); List users = new ArrayList(); for (int i=0; i<10; i++) { User user = new User(); user.setUsername("张三_" + i); user.setAge(23 + i); user.setGroup(group); users.add(user); } request.setAttribute("users", users); Map map = new HashMap(); map.put("k1", "v1"); map.put("k2", "v2"); map.put("k3", "v3"); map.put("k4", "v4"); request.setAttribute("map", map); //forTokens request.setAttribute("strTokens","1#2#3#4#5"); request.getRequestDispatcher("/jsp_core.jsp").forward(request, response); } }
这里的Servlet跟不适用jstl没有任何差别。这里制造了一些实体结构、空、数组、map数据,为下一步的jstl的访问,做演示基础。
4、使用jstl的核心库访问、控制数据显示:
jsp_core.jsp文件:
<%@ page language="java" contentType="text/html; charset=GBK" pageEncoding="GBK"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ page import="java.util.*"%> <%@ page import="com.bjpowernode.jstl.*"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <title>测试jstl核心库,引入tld文件</title> </head> <body> <h1>测试jstl核心库</h1> <br> <li>采用C:out标签</li> <br> hello(使用标签): <c:out value="123"></c:out> <br> hello(使用标签): <c:out value="hello"></c:out> <br> hello(使用EL表达式):${hello } <br> hello(default):${hello123 } <br> hello(使用缺省值): <c:out value="${hello123}" default="没有值"></c:out> <br> hello(使用缺省值): <c:out value="${hello123 }">没有值</c:out> <br> welcome(使用EL表达式):${welcome } <br> welcome(使用jst标签,escapeXml="true"): <c:out value="${welcome }" escapeXml="true"></c:out> <br> welcome(使用jst标签,escapeXml="false"): <c:out value="${welcome }" escapeXml="false"></c:out> <br> <p> <c:set value="root" var="userid" /> ${userid }<br> <li>测试c:set,c:remove</li> <br> <c:set value="root" var="userid" /> userid:${userid } <br> <c:remove var="userid" /> userid1:${userid } <br> <li>测试c:set、c:remove</li><br> 测试set: <c:set value="root" var="userId"> </c:set><br> userId2:${userId } 测试set(body scope): <c:set var="userId" scope="page"> root </c:set><br> userId3:${userId } 测试remove <br> userId:${userId } <br> <c:remove var="userId" /> 移除后:userId:${userId } <br> <p> <li>条件控制标签:c:if</li> <br> 测试if控制: <c:if test="${v1 lt v2 }">v1小于v2</c:if> <br> <li>条件控制标签:c:when c:chose c:otherwise</li> <br> <c:choose> <c:when test="${v1 gt v2 }"> v1大于v2<br> </c:when> <c:otherwise> v1不大于v2<br> </c:otherwise> </c:choose> <c:choose> <c:when test="${empty userList }"> userList为空<br> </c:when> <c:otherwise> 存在用户数据!<br> </c:otherwise> </c:choose> <p> <li>jsp语法,显示表格</li> <table> <tr> <td>姓名</td> <td>年龄</td> <td>组别</td> </tr> <% //取出数据 List userList =(List)request.getAttribute("users"); if(userList==null||userList.size()==0){ %> <tr> <td colspan="3">没有数据</td> </tr> <% }else{ %> <% for(int i =0;i<userList.size();i++){ User user = (User)userList.get(i); /* for(Iterator iter= userList.iterator();iter.hasNext();){ User user = (User)iter.next(); */ %> <tr> <td><%=user.getUsername() %></td> <td><%=user.getAge() %></td> <td><%=user.getGroup().getName() %></td> </tr> <% } } %> </table> <li>循环控制标签c:forEach</li> <br> 测试c:forEach: <table border="1"> <tr> <td>用户名</td> <td>年龄</td> <td>所属组</td> </tr> <c:choose> <c:when test="${empty users}"> <tr> <td colspan="3">没有符合条件的数据</td> </tr> </c:when> <c:otherwise> <c:forEach items="${users}" var="user"> <tr> <td>${user.username }</td> <td>${user.age }</td> <td>${user.group.name }</td> </tr> </c:forEach> </c:otherwise> </c:choose> </table> <li>循环控制标签c:forEach varSatues</li> <br> <table> <tr> <td>用户名</td> <td>年龄</td> <td>所属组</td> </tr> <c:choose> <c:when test="${empty users }"> <tr> <td colspan="3">没后符合条件的语句</td> </tr> </c:when> <c:otherwise> <c:forEach items="${users}" var="user" varStatus="vs"> <c:choose> <c:when test="${vs.count mod 2 ==0 }"> <tr bgcolor="yellow"> </c:when> <c:otherwise> <tr> </c:otherwise> </c:choose> <td>${user.username }</td> <td>${user.age }</td> <td>${user.group.name }</td> </tr> </c:forEach> </c:otherwise> </c:choose> </table> <p> <li>循环控制标签c:forEach begin end step</li><br> <table border="1"> <tr> <td>用户名</td> <td>年龄</td> <td>所属组</td> </tr> <c:choose> <c:when test="${empty users }" > <tr> <td colspan="3">没后符合条件的语句</td> </tr> </c:when> <c:otherwise> <c:forEach items="${users }" var ="user" begin ="2" end ="8" step="2"> <tr> <td> ${user.username }</td> <td>${user.age }</td> <td>${user.group.name }</td> </tr> </c:forEach> </c:otherwise> </c:choose> </table> <p> <li>演示forEach输出 Map 值</li><br> <c:forEach items="${map}" var ="entry"> ${ entry.key},${entry.value }<br> </c:forEach> <p> <li>演示使用forTokes循环</li> <c:forTokens items="${strTokens }" delims="#" var="v" > ${v }<br> </c:forTokens> <p> <li> catch标签 </li> <% try{ Integer.parseInt("abcv"); }catch(NumberFormatException e){ out.print(e.getMessage()); } %> <c:catch> ${msg } </c:catch> <p> <li>c: url c:param</li> <c:url value="http://localhost:8080/drp4.7/sysmgr/validate.jsp" var ="u"> <c:param name="userId" value="zhangsanfeng"></c:param> <c:param name="age" value="180"></c:param> </c:url> ${u }<br> <li>c:redirect</li> <c:redirect url="/login.jsp" context="/drp4.7"></c:redirect> </body> </html>
注意需要添加对jstl的引用:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
不同版本的jstl,uri的路径是有所区别的,初学者,可以从jstl Library—>jstl-impl.jar—>META-INF目录下的具体的tld文件中复制。
通过上面的代码就可以看出使用jstl要比嵌入java代码简洁的多,尤其是在循环方面更是如此。具体语法,比较简单,而且文章中也已经附上了帮助文档,这里不做赘述,关键还是要多实践。
五、疑问:
jstl方便在jsp中构造页面的显示,对于树形结构,如果是在servlet中结合数据库递归+html代码实现,一些优秀的框架,如ext等已经做的很好了,但是对于使用jstl有什么好的方法吗?