【JSTL_EL:标准标签库和表达式语言】
一. EL表达式
1.1 基本概念
EL(Expression Language) 是为了使JSP写起来更加简单。表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP 中简化表达式的方法,让Jsp的代码更加简化。EL 语法很简单,使用上很方便。${}是其语法的关键标志
1.2 作用
EL表达式中定义了一些可以帮助我们快捷从域对象中取出数据的写法,基本语法为
${域标志.数据名.属性名(可选)} |
---|
四个域标志关键字分别为
requestScope request域
sessionScope session域
applicationScope application域
pageScope page域
1.3 域对象中获取数据
servlet
protected void service(HttpServletRequest req, HttpServletResponse resp_) _throws ServletException, IOException { _User user = new User**(1,“zs”,“111111”,20); List<_**String**_> list = new ArrayList<>(); list.add(“aa”); list.add(“bb”); list.add(“cc”)**; //request(存放业务数据) req.setAttribute**(“list”, list); req.setAttribute(“msg”, “一次请求有效”)**; //session(存放用户信息) HttpSession session = req.getSession**(); session.setAttribute(“user”, user); session.setAttribute(“msg”, “一次会话有效”)**; //application(项目共享的数据) ServletContext application = req.getSession**().getServletContext(); application.setAttribute(“msg”, “整个项目共享的数据”); req.getRequestDispatcher(“/index.jsp”).forward(req,resp);}_** |
---|
jsp
_<%@ _page contentType=”text/html;charset=UTF-8“ language=”java“ %> __<_html> <_head_> <_title_>_$Title$</_title> <_body_> _ <%—通过脚本表达式在域中获取数据—%> _Request: <%=request.getAttribute**(“list”)%> <_br_> Session: <%=session.getAttribute(“user”)%> <_br_> Application: <%=application.getAttribute(“msg”)%> <_br_> <_hr_> **<%—方式一: 通过EL表达式从域中获取数据—%> Request: ${requestScope.list**} <_br_> ${requestScope.list[1]} <_br_> ${requestScope.msg}<_br_><_br_> Session: ${sessionScope.user} <_br_> ${sessionScope.user.id} <_br_> ${sessionScope.user.name} <_br_> ${sessionScope.user.age} <_br_> ${sessionScope.msg}<_br_><_br_> Application: ${applicationScope.msg} <_br_> <_hr_> **<%—方式二: 通过EL表达式从域中获取数据—%> ${list**} <_br_> ${user} <_br_> ${msg} <_br_> _** |
---|
EL表达式可以从request对象中取出请求参数
<%—el表达式从request中获取请求参数—%>${param.username} |
---|
1.4 表达式的原理
·EL的四个范围和JSP的四个范围对应,分别为pageContextScope、requestScope、sessionScope,applicationScope
Object value = null; value = pageContext.getAttribute(key); if(value==null){ value = request.getAttribute(key); if(value==null){ value = session.getAttribute(key); if(value == null){ value = application.getAttribute(key); if(value==null){ value= “”; } } }} return value; |
---|
1.5 获取对象属性的原理
·底层采用了反射机制, 调用的是相应属性的getter方法
${requestScope.user.username } //获取对象 User value =(User)request.getAttribute(“user”); //获取对象对应的类 Class clazz = value.getClass(); //通过属性获取属性对应的操作方法 Method method = clazz.getMethod(“get”+”Userame”); //开始执行 Object returnValue = method.invoke(value); |
---|
总结:
EL表达式定义在JSP页面上, 在转译之后的java文件中, 会被转化成java代码
EL表达式是一种后台技术, 服务器上运行, 不是在浏览器上运行,不能用于HTML页面
EL表达式底层是通过反射实现的, 在获取对象属性值时是通过对象的get方法实现的
1.6 常用的运算符
常用的算术运算符
常用的关系运算符
3) 常用关系运算符
${!(num==10)}
${not (num==10)}
4) 条件运算符
${条件表达式? 语句1 : 语句2} |
---|
5) 验证运算符
${empty 表达式} 返回布尔值判断表达式是否为”空”值,null值、无元素的集合或数组、长度为零的String被认为是空值。 |
---|
代码演示:
<% int score =(_int)(_Math.random()*101); pageContext.setAttribute(“score”,score);%> ${score} ${score ge 90 and score le 100?“A”:“”} ${score ge 80 and score le 89?“B”:“”} ${score ge 70 and score le 79?“C”:“”} ${score ge 60 and score le 69?“D”:“”} ${score lt 60?“E”:“”}<_br/>_ **<% pageContext.setAttribute(“a”,null); pageContext.setAttribute(“b”,“”); int[] arr ={}; pageContext.setAttribute(“arr”,arr); List list =new ArrayList() ; pageContext.setAttribute(“list”,list);%> 判断null${empty a?“数据没找到”:a} <_br/>判断””${empty b} <_br_>判断空数组${empty arr} <_br_>判断空集合${empty list} <_br_>判断空集合${list.size() eq 0} <_br_>_** |
---|
二. JSTL表达式
2.1 概念
JSP中可以使用EL表达式取出域对象中的数据, 但是仍然避免不了还是要在页面中书写一些java代码(如: 集合的遍历), 处理比较繁琐, 且代码不容易维护
2.2 作用
开发人员可以利用JSTL和EL来开发Web程序,取代传统直接在页面上嵌入Java程序的做法,以提高程序的阅读性、维护性和方便性。在jstl中, 提供了多套标签库, 用于方便在jsp中完成或简化相关操作
2.3 使用方式
- 需要在项目中导入jstl-1.2.jar ,jstl在后台由java代码编写, jsp页面中通过标签进行使用, 使用标签时, 会自动调用后台的java方法(jar包中的方法)
- 标签库的引入语法格式 | <%@ taglib uri=”标签库的定位” prefix=”前缀(简称)” %> | | —- |
3) 常用标签的引入
核心标签的引入
<%@ taglib prefix=”c“ uri=”http://java.sun.com/jsp/jstl/core“%> |
---|
格式化标签的引入
_<%@ _taglib prefix=”fmt“ uri=”http://java.sun.com/jsp/jstl/fmt“ %> |
---|
2.4 常用标签的使用
2.4.1 操作域对象的标签
<_c:out> _用来将指定内容输出的标签 <_c:set> _用来设置属性范围值的标签, 指定作用范围是什么域 <_c:remove> _用来删除指定数据的标签 |
---|
<%—向四个域中放入数据 setAttribute—%> <c:set var=”msg” value=”pageScopeMsg” scope=”page” ></c:set> <c:set var=”msg” value=”requestScopeMsg” scope=”request” ></c:set> <c:set var=”msg” value=”sessionScopeMsg” scope=”session” ></c:set> <c:set var=”msg” value=”applicationScopeMsg” scope=”application” ></c:set> <%—从四个域中取出数据 getAttribute—%> ${pageScope.msg} ${requestScope.msg} ${sessionScope.msg} ${applicationScope.msg} <hr/> <%—c remove 移除指定域中的数据的 removeAttribute —%> <c:remove var=”msg” scope=”page”></c:remove> <c:remove var=”msg” scope=”session”></c:remove> <c:remove var=”msg” scope=”request”></c:remove> <c:remove var=”msg” scope=”application”></c:remove> <hr/> <%—c out 输出标签中取出的域对象中的数据 —%> <c:out value=”${pageScope.msg}” default=”msg信息未找到”></c:out> <c:out value=”${requestScope.msg}” default=”msg信息未找到”></c:out> <c:out value=”${sessionScope.msg}” default=”msg信息未找到”></c:out> <c:out value=”${applicationScope.msg}” default=”msg信息未找到”></c:out> |
---|
2.4.2单条件判断
<%— test 相当于 if(判断条件) var 判断条件的结果 保存到域对象中 数据的名称 scope 控制操作的域 —%> _<_c:if test =“EL条件表达式”> 满足条件执行 </c:if > |
---|
<%pageContext.setAttribute(“score”,99);%>_分数:${score} 级别: <c:if test=”${score ge 90 and score le 100}” var=”f1”>A</c:if> <c:if test=”${score ge 80 and score lt 90}” var=”f2”>B</c:if> <c:if test=”${score ge 70 and score lt 80}” var=”f3”>C</c:if> <c:if test=”${score ge 60 and score lt 70}” var=”f4”>D</c:if> <c:if test=”${ score lt 60}” var=”f5”>E</c:if> |
---|
2.4.3多条件判断
<_c:choose > __ <_c:when test =“EL表达式”> 满足条件执行 </_c:when> _ … <_c:otherwise> _ 不满足上述when条件时执行 </_c:otherwise>_</c:choose > |
---|
<c:choose> <c:when test=”${score ge 90}”>A</c:when> <c:when test=”${score ge 80}”>B</c:when> <c:when test=”${score ge 70}”>C</c:when> <c:when test=”${score ge 60}”>D</c:when> <c:otherwise>E</c:otherwise> </c:choose> |
---|
2.4.4 循环标签
<%—相当于for循环—%> var: 迭代变量 begin: 迭代起始值 end: 迭代结束值 step: 迭代变量变化的步长 <c:forEach var=”i” begin=”1” end=”9” step=”1”> … </_c:forEach>_ <%—相当于for each循环—%> var: 迭代变量 items: 集合 _<_c:forEach var=“循环变量” items=“集合”> … </_c:forEach>_ <%—特殊字符串, 按照指定的分隔符, 分割遍历—%><_c:forTokens items=”集合” delims=”特殊字符” var=”循环变量”> _… </_c:forEach>_ |
---|
<%—打印99乘法表—%> <_c:forEach begin=”1” end=”9” step=”1” var=”i”> __ <_c:forEach begin=”1” end=”${i}” step=”1” var=”j”> __ ${j} * ${i} = ${ji*} </_c:forEach> <_br_> _ |
---|
2.5 案例
| _<%@_page import=”java.sql.Date“%>
_<%@ _page language=”java“ import=”java.util.*“ pageEncoding=”UTF-8“%>
_<%@ _page import=”com.bjsxt.pojo.Employee“ %>
_<%@_taglib prefix=”c“ uri=”http://java.sun.com/jsp/jstl/core“%>
_<%@_taglib prefix=”fmt“ uri=”http://java.sun.com/jsp/jstl/fmt“ %>
__<_html>
<_head_>
<_title_>_My JSP ‘jstlel.jsp’ starting page**</_title>
_</_head>
<_body_><%
**/1.准备数据/
int n=70;//基本类型
double avgScore = 99.45678;//基本类型
Employee emp=new Employee**()**;//引用类型
emp.setEid**(1);
emp.setEname(“张晓红”);
emp.setBirth(**Date._valueOf(“1999-12-12”));
String [] strs = {“Java”,“Oracle”,“JSP”,“HTML”};//数组
_String courses=“Java,Oracle,JSP,HTML,Servlet”;//特殊的字符串
String courses2=“Java#Oracle#JSP#HTML#Servlet”;//特殊的字符串
String str = null;
String str3 = “”;
List list = new ArrayList**()**;//分配空间,没有元素
list.add**(90);
list.add(80);
List list2 =null**;//没有分配空间
List list3 =new ArrayList**()**;//分配空间,没有元素 size()==0
Map**<_**String,String**_> map = new HashMap<_**String,String**_>()**;//Map
map.put**(“cn”, “China”);
map.put(“fr”, “France”)**;
//setAttribute
request.setAttribute**(“n”,n);
request.setAttribute(“avgScore”,avgScore);
request.setAttribute(“emp”,emp);
request.setAttribute(“strs”,strs);
request.setAttribute(“courses”,courses);
request.setAttribute(“courses2”,courses2);
request.setAttribute(“now”,new java.util.Date());
request.setAttribute(“list”, list);
request.setAttribute(“list2”, list2);
request.setAttribute(“list3”, list3);
request.setAttribute(“map”, map);
request.setAttribute(“str”, str);
request.setAttribute(“str3”, str3)**;%>
//2.使用JSTL和EL输出
<_h3>JSTL和EL标签的使用n:${requestScope.n}<_hr_>avgScore:${requestScope.avgScore} <_br_>
<%—如果分数 90-100 A 80-90 B 80—C —%>**<_c:if test="${**requestScope.avgScore>=90 && requestScope.avgScore<=100**}"_>A
<_c:if test="${**requestScope.avgScore>=80 && requestScope.avgScore<90**}"_>B
<_c:if test="${**requestScope.avgScore<80**}"_>C
<_br_>
<%—if()..else if()…else{}—%>**<_c:choose_>
<_c:when test="${**requestScope.avgScore>=90**}"_>A
<_c:when test="${**requestScope.avgScore>=80**}"_>B
<_c:when test="${**requestScope.avgScore>=70**}"_>C
<_c:otherwise_>D
<_br_>分数:<_fmt:formatNumber maxFractionDigits="2" value="${**requestScope.avgScore**}"_>
<_hr_>姓名:${requestScope.emp.ename}<_br_>日期:${requestScope.emp.birth}<_br_>日期:<_fmt:formatDate value="${**requestScope.emp.birth**}" pattern="yyyy年MM月dd日"_>
<_hr_>
<_c:forEach items="${**requestScope.strs**}" var="s" varStatus="vs"_>
${s}—>${vs.index}—->${vs.count} <_br_>
<_hr_>
<%—如果字符串是按照逗号进行分割时候,就这种情况是可以直接进行遍历的—%>**<_c:forEach items="${**requestScope.courses**}" var="s"_>
${s}—->
<_hr_>
<_c:forEach items="${**requestScope.courses2**}" var="s"_>
${s}—->
<_hr_>
<%—进行特殊字符串的分割—%>**<_c:forTokens items="${**requestScope.courses2**}" delims="#" var="s"_>
${s}—->
<_hr_>
<_c:forEach items="${**requestScope.map**}" var="m"_>
${m.key}—->${m.value}
<_hr_>请选择每页显示的条数:<_select_>
<_c:forEach begin="10" step="10" end="100" var="size"_>
<_option_>${size}
_</_html>_** |
| —- |