服务器端渲染技术02
11.EL表达式
11.1EL表达式介绍
-
EL表达式全称:Expression Language,是表达式语言
-
EL表达式主要是代替jsp页面的表达式脚本
-
EL表达式输出数据时,比jsp的表达式脚本简洁
-
EL表达式基本语法:$
底层其实走的还是jsp表达式脚本,可以理解为就是一个语法糖
11.2EL表达式快速入门
el_qs.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> el表达式的快速入门 el表达式的快速入门
<% request.setAttribute("name","星星之火,可以燎原"); %> <%-- 1.如果name是null,用request.getAttribute("name")返回的就是null字符串 2.如果name是null,用el表达式返回的则是空串 "" --%> 1.jsp 表达式脚本
名字:<%=request.getAttribute("name")%>
2.el 表达式
名字:${name}
注意:
-
EL表达式在输出null时,输出的是空串""
-
jsp脚本在输出null时,输出的是 “null” 字符串
11.3EL常用输出形式
EL表达式常用输出Bean的普通属性,数组属性,List集合属性和map集合属性
应用实例
book.java:
package com.li.entity; import java.util.Arrays; import java.util.List; import java.util.Map; public class Book { private String name;//书名 private String[] writer;//作者 private List reader;//读者 private Map topics;//评价 public String getName() { return name; } public void setName(String name) { this.name = name; } public String[] getWriter() { return writer; } public void setWriter(String[] writer) { this.writer = writer; } public List getReader() { return reader; } public void setReader(List reader) { this.reader = reader; } public Map getTopics() { return topics; } public void setTopics(Map topics) { this.topics = topics; } @Override public String toString() { return "Book{" + "name='" + name + '\'' + ", writer=" + Arrays.toString(writer) + ", reader=" + reader + ", topics=" + topics + '}'; } }
el_output.jsp:
<%@ page import="com.li.entity.Book" %> <%@ page import="java.util.List" %> <%@ page import="java.util.Map" %> <%@ page import="java.util.ArrayList" %> <%@ page import="java.util.HashMap" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> el表达式输出数据演示 el表达式输出数据演示
<% //创建一个Book对象初始化,并放入相关属性 Book book = new Book(); book.setName("昆虫总动员"); book.setWriter(new String[]{"jack", "tomas"}); ArrayList readers = new ArrayList<>(); readers.add("小李"); readers.add("小王"); book.setReader(readers); //创建topics HashMap topics = new HashMap<>(); topics.put("topic1", "这是我看过的最好的动画片"); topics.put("topic2", "不错的电影~~"); book.setTopics(topics); //把book放入到request域对象中 request.setAttribute("bookKey", book); %> book对象:${bookKey}
book.name=${bookKey.name}
<%--这里输出的是数组对象,因为数组没有重写toString方法--%> book.writer=${bookKey.writer}
第一个作者book.writer[0]=${bookKey.writer[0]}
<%--这里可以输出具体的值,因为list底层重写了toString方法--%> book.readers=${bookKey.reader}
<%--第二个读者book.readers[1]=${bookKey.reader.get(1)}
--%> 第二个读者book.readers[1]=${bookKey.reader[1]}
book.topics=${bookKey.topics}
<%--map不能以索引的方式来取值--%> 第一个评价=${bookKey.topics.get("topic1")}
第一个评价=${bookKey.topics["topic1"]}
11.4EL运算操作符
EL的运算操作符和java基础的操作符在概念和用法上都是一样的,只是形式上有些变化。
-
基本语法:
${运算表达式} -
关系运算
-
逻辑运算
-
算术运算
应用实例
<%@ page contentType="text/html;charset=UTF-8" language="java" %> el运算符 el运算符
<% request.setAttribute("num1", 90); request.setAttribute("num2", 30); %> num1+num2=${num1+num2}
num1>num2?=${num1>num2}
11.5EL的empty运算
- empty运算可以判断一个数是否为空,如果为空,返回true,否则返回false
- 以下几种情况为空:
- 值为null
- 值为空串时
- 值是Object类型数据,但长度为零时
- list集合,元素个数为零时
- map集合,元素个数为零时
应用实例
<%@ page import="java.util.ArrayList" %> <%@ page import="java.util.HashMap" %><%-- <%@ page contentType="text/html;charset=UTF-8" language="java" %> el empty的运算 <% request.setAttribute("k1", null);//null request.setAttribute("k2", "");//空串 request.setAttribute("k3", new Object[]{});//为空的Object数组 request.setAttribute("k4", new ArrayList<>());//为空的list集合 request.setAttribute("k5", new HashMap<>());//为空的map集合 %> k1是否为空=${empty k1}
k2是否为空=${empty k2}
k3是否为空=${empty k3}
k4是否为空=${empty k4}
k5是否为空=${empty k5}
11.6EL的三元运算
-
表达式1?表达式2:表达式3
-
如果表达式1的值为真,返回表达式2的值,反之返回表达式3的值
11.7EL的11个隐含/内置对象

下面以pageScope,requestScope,sessionScope,applicationScope四个常用的隐含对象为例子演示。
演示el常用的四个隐含对象(域对象)
<%@ page contentType="text/html;charset=UTF-8" language="java" %> 演示el的四个常用的隐含对象(域对象) 演示el的四个常用的隐含对象(域对象)
<% request.setAttribute("k1", "request-k1数据"); pageContext.setAttribute("k1", "pageContext-k1数据"); session.setAttribute("k1", "session-k1数据"); application.setAttribute("k1", "application-k1数据"); %> 1.jsp脚本方式获取
<%=request.getAttribute("k1")%> 2.el方式来获取域对象的数据
request域中的k1=${requestScope.k1}
pageContext域中的k1=${pageScope.k1}
session域中的k1=${sessionScope.k1}
application域中的k1=${applicationScope.k1}
11.7.1pageContext对象的使用
-
我们可以通过pageContext.request.xxx来获取和http协议相关的信息:
通过request对象来获取和HTTP协议相关的数据:
- request.getScheme() 它可以获取请求的协议
- request.getServerName() 获取请求的服务器 ip 或域名
- request.getServerPort() 获取请求的服务器端口号
- getContextPath() 获取当前工程路径
- request.getMethod() 获取请求的方式(GET 或 POST)
- request.getRemoteHost() 获取客户端的 ip 地址
- session.getId() 获取会话的唯一标识
例子
<%@ page contentType="text/html;charset=UTF-8" language="java" %> pageContext 对象的使用 pageContext 对象的使用
<%-- //通过 request 对象来获取和 HTTP 协议相关的数据 request.getScheme() 它可以获取请求的协议 request.getServerName() 获取请求的服务器 ip 或域名 request.getServerPort() 获取请求的服务器端口号 getContextPath() 获取当前工程路径 request.getMethod() 获取请求的方式(GET 或 POST) request.getRemoteHost() 获取客户端的 ip 地址 session.getId() 获取会话的唯一标识 --%>
协议: ${ pageContext.request.scheme }
服务器 ip:${ pageContext.request.serverName }
服务器端口:${ pageContext.request.serverPort }
工程路径:${ pageContext.request.contextPath }
请求方法:${ pageContext.request.method }
客户端 ip 地址:${ pageContext.request.remoteHost }
会话 id :${ pageContext.session.id }
使用 jsp 表达式脚本获取如上信息
ip 地址: <%=request.getRemoteHost() %>
会话 id :<%=request.getRequestedSessionId()%>
... 使用 el 表达式形式获取信息-简化写法
<% //可以将request对象放到pageContext属性中,通过key可以很方便地取出,从而简化写法 pageContext.setAttribute("req", request); %> ip 地址: ${req.remoteHost}
获取请求方法: ${req.method}
客户端 ip 地址:${ req.remoteHost }
...
12.JSTL
12.1JSTL介绍
-
JSTL(Java server pages standarded tag library,即JSP标准标签库。
-
EL表达式是为了替换jsp中的表达式脚本,JSTL是为了替换代码脚本<%%>,这样可以使jsp页面变得更加简洁。
-
JSTL由五个标签库组成:

-
使用JSTL,需要导入相关的jar包:
12.2快速入门
-
将两个jar包直接复制粘贴到web应用程序的WEB-INF\lib目录下,add as library
-
在jsp页面的引入标签,要放在文件第一行
-
导入jstl jar包后,要重新发布web工程,否则不识别jstl
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> jstl的快速入门 jstl的快速入门
<%-- 1.c: if ...标签类似 2.if(10>2){ out.println("xxx") } --%> if test="${10>2}"> 10>2成立~~~
if>
12.3core核心库
12.3.1 标签
例子:
set标签可以往域中保存数据
- 等价于
域对象.setAttribute(key,value); - scope 属性设置保存到哪个域
- page表示PageContext域(默认值)
- request表示Request域
- session表示Session域
- application表示ServletContext域
- var 属性设置 key 是什么
- value 属性设置值
例子
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> c:set标签的使用 c:set标签的使用
<% //原来的写法 //request.setAttribute("email","tomas@qq.com"); %> <%--jstl的写法--%> "request" var="name" value="tomas"> <%--c:set-name的值:${name} 或者--%> c:set-name的值:${requestScope.name}
12.3.2 标签
例子:
- if标签用来做if判断
- test属性表示判断的条件(用EL表达式输出)
例子
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> c:if标签使用 c:if标签使用
"request" var="num1" value="20"/> "request" var="num2" value="10"/> if test="${num1>num2}"> ${num1}>${num2}
if>
12.3.3标签
介绍:多路判断。跟switch...case...default非常接近
例子
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> c:choose标签的使用 <% request.setAttribute("scope", 59); pageContext.setAttribute("k1", "pageContext-k1"); request.setAttribute("k1", "request-k1"); session.setAttribute("k1", "session-k1"); application.setAttribute("k1", "application-k1"); %> <%--如果这样写:${requestScope.scope} 就是明确指定从request域对象取出数据 --%> <%--如果这样写:${scope} 就按照下面的域范围从小到大的开始找 pageContext ->request-> session->application --%> k1=${k1}
c:choose标签的使用
"${requestScope.scope > 80}"> ${scope}-成绩优秀!
"${requestScope.scope > 60}"> ${scope}-成绩及格!
${scope}-成绩不及格,继续努力!
12.3.4 标签
介绍:c:forEach标签用来遍历输出,主要有4种形式
- 普通遍历输出i到j
- 遍历数组
- 遍历Map
- 遍历List
例子
<%@ page import="java.util.HashMap" %> <%@ page import="java.util.ArrayList" %> <%@ page import="com.li.entity.Monster" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> c:forEach标签 c:forEach标签
第一种遍历方式:从i到j
<%-- 1.遍历1到5 2.begin属性设置开始的索引,end属性设置结束的索引 3.var属性表示循环的变量(也就是当前正在遍历到的数据) 4.等价于 for(int i = 1; i < = 5; i++){} 5.默认情况情况下,i的值每次会递增 1 6.可以使用step属性来设置增量 --%> "1" end="5" var="i"> - 排名=${i}
第二种遍历方式:遍历数组
<% request.setAttribute("sports", new String[]{"打篮球", "乒乓球"}); %> <%-- 1.item属性指定要遍历的集合/数组 2.var 自定义变量,每次取出的数据会存放到该变量中 3.等价于 for(Object item:arr){} 相当于每循环一次,就在items指定的数组中, 取出一个数据存放到var自定义的变量中, 直至取完数据就退出循环 --%> "${requestScope.sports}" var="sp"> 运动名称=${sp}
第三种遍历方式:遍历Map
<% HashMap map = new HashMap<>(); map.put("key1", "北京"); map.put("key2", "上海"); map.put("key3", "天津"); request.setAttribute("cities", map); %> <%-- 1.item:遍历的map集合 2.var:遍历到的数据 3.entry.key:取出key 4.entry.value:取出值 --%> "${requestScope.cities}" var="city"> 城市信息=${city.key}--${city.value}
第四种遍历方式:遍历List
<% ArrayList monsters = new ArrayList<>(); monsters.add(new Monster(100, "小妖怪", "巡山的")); monsters.add(new Monster(200, "大妖怪", "做饭的")); monsters.add(new Monster(300, "老妖怪", "打扫位置的")); request.setAttribute("monsters", monsters); %> <%-- items 表示遍历的集合 var 表示遍历到的数据 begin 表示遍历的开始索引值 ,从 0 开始计算 end 表示结束的索引值 step 属性表示遍历的步长值 varStatus 属性表示当前遍历到的数据的状态,可以得到 step,begin,end 等属性值 --%> "${requestScope.monsters}" var="monster"> 妖怪信息=${monster.id}-${monster.name}-${monster.skill}
13.练习
需求分析:使用jsp+servlet+jstl+el完成查询-显示案例,需求如下:
- 点击超链接,可以显示所有的妖怪信息
- 要求显示的数据在servlet中准备,并放入到request域对象中
- 扩展,如果要求增加根据薪水sal条件过滤,怎么处理?

练习
思路:通过query.jsp将查询条件传到queryServlet,在servlet中判断符合条件的数据,并放到request域中,通过请求转发到显示页面view.jsp中,在view页面通过jstl循环标签显示。
思路二:过滤的条件可以在view中通过jstl的if标签中判断,通过servlet将过滤条件发送给view
query.jsp:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%-- Created by IntelliJ IDEA. User: li Date: 2022/11/27 Time: 0:07 Version: 1.0 --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> query 查询妖怪
请输入查询的最低工资:"text" name="sal"/>
"submit" value="点击查询"/>
QueryServlet:
package com.li.servlet; import com.li.entity.Monster; import com.utils.WebUtils; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; import java.util.ArrayList; @WebServlet(name = "QueryServlet", urlPatterns = "/queryServlet") public class QueryServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("QueryServlet was run..."); //所有妖怪的数据 ArrayList allMonsters = new ArrayList<>(); allMonsters.add(new Monster(100, "小妖怪", "巡山的", 345.7)); allMonsters.add(new Monster(200, "大妖怪", "做饭的", 1345.7)); allMonsters.add(new Monster(300, "老妖怪", "打扫位置的", 11345.7)); //获取筛选条件 String selectSal = request.getParameter("sal"); //String转成double double selectNum = WebUtils.parseDouble(selectSal, 0); //筛选 //用来放筛选数据的list ArrayList vaildMonsters = new ArrayList<>(); for (Monster monster : allMonsters) { if (monster.getSal() >= selectNum) { vaildMonsters.add(monster); } } //将合法数据放到域对象中 request.setAttribute("vaildMonsters", vaildMonsters); //请求转发到显示页面 request.getRequestDispatcher("/hw/view.jsp").forward(request, response); } }
Monster:
package com.li.entity; public class Monster { private Integer id; private String name; private String skill; private double sal; public Monster(Integer id, String name, String skill, double sal) { this.id = id; this.name = name; this.skill = skill; this.sal = sal; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSkill() { return skill; } public void setSkill(String skill) { this.skill = skill; } public double getSal() { return sal; } public void setSal(double sal) { this.sal = sal; } @Override public String toString() { return "Monster{" + "id=" + id + ", name='" + name + '\'' + ", skill='" + skill + '\'' + ", sal=" + sal + '}'; } }
WebUtils:
package com.utils; public class WebUtils { public static double parseDouble(String strNum, int defaultVal) { try { return Double.parseDouble(strNum); } catch (NumberFormatException e) { System.out.println(strNum + "不能转成整数"); } return defaultVal; } }
view.jsp:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%-- Created by IntelliJ IDEA. User: li Date: 2022/11/27 Time: 0:13 Version: 1.0 --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> view 显示妖怪信息
"1px" width="300px"> id name job sal "${requestScope.vaildMonsters}" var="monster"> ${monster.id} ${monster.name} ${monster.skill} ${monster.sal}