【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-8language=”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 常用的运算符

  1. JSTL_EL:标准标签库和表达式语言_MVC分层开发 - 图1常用的算术运算符

  2. JSTL_EL:标准标签库和表达式语言_MVC分层开发 - 图2常用的关系运算符

JSTL_EL:标准标签库和表达式语言_MVC分层开发 - 图33) 常用关系运算符
${!(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 使用方式

  1. 需要在项目中导入jstl-1.2.jar ,jstl在后台由java代码编写, jsp页面中通过标签进行使用, 使用标签时, 会自动调用后台的java方法(jar包中的方法)
  2. 标签库的引入语法格式 | <%@ taglib uri=”标签库的定位” prefix=”前缀(简称)” %> | | —- |

3) 常用标签的引入
核心标签的引入

<%@ taglib prefix=”curi=”http://java.sun.com/jsp/jstl/core“%>

格式化标签的引入

_<%@ _taglib prefix=”fmturi=”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
=”javaimport=”java.util.*pageEncoding=”UTF-8%>
_
<%@ _page import
=”com.bjsxt.pojo.Employee%>
_
<%@_taglib prefix
=”curi=”http://java.sun.com/jsp/jstl/core%>
_
<%@_taglib prefix
=”fmturi=”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>_** | | —- |