day24-服务器端渲染技术02
服务器端渲染技术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" %> <html> <head> <title>el表达式的快速入门</title> </head> <body> <h1>el表达式的快速入门</h1> <% request.setAttribute("name","星星之火,可以燎原"); %> <%-- 1.如果name是null,用request.getAttribute("name")返回的就是null字符串 2.如果name是null,用el表达式返回的则是空串 "" --%> <h3>1.jsp 表达式脚本</h3> 名字:<%=request.getAttribute("name")%><br/> <h3>2.el 表达式</h3> 名字:${name}<br/> </body> </html>

注意:
-
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<String> reader;//读者 private Map<String,String> 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<String> getReader() { return reader; } public void setReader(List<String> reader) { this.reader = reader; } public Map<String, String> getTopics() { return topics; } public void setTopics(Map<String, String> 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" %> <html> <head> <title>el表达式输出数据演示</title> </head> <body> <h1>el表达式输出数据演示</h1> <% //创建一个Book对象初始化,并放入相关属性 Book book = new Book(); book.setName("昆虫总动员"); book.setWriter(new String[]{"jack", "tomas"}); ArrayList<String> readers = new ArrayList<>(); readers.add("小李"); readers.add("小王"); book.setReader(readers); //创建topics HashMap<String, String> topics = new HashMap<>(); topics.put("topic1", "这是我看过的最好的动画片"); topics.put("topic2", "不错的电影~~"); book.setTopics(topics); //把book放入到request域对象中 request.setAttribute("bookKey", book); %> book对象:${bookKey}<br/><br/> book.name=${bookKey.name}<br/><br/> <%--这里输出的是数组对象,因为数组没有重写toString方法--%> book.writer=${bookKey.writer}<br/><br/> 第一个作者book.writer[0]=${bookKey.writer[0]}<br/><br/> <%--这里可以输出具体的值,因为list底层重写了toString方法--%> book.readers=${bookKey.reader}<br/><br/> <%--第二个读者book.readers[1]=${bookKey.reader.get(1)}<br/>--%> 第二个读者book.readers[1]=${bookKey.reader[1]}<br/><br/> book.topics=${bookKey.topics}<br/><br/> <%--map不能以索引的方式来取值--%> 第一个评价=${bookKey.topics.get("topic1")}<br/><br/> 第一个评价=${bookKey.topics["topic1"]} </body> </html>

11.4EL运算操作符
EL的运算操作符和java基础的操作符在概念和用法上都是一样的,只是形式上有些变化。
-
基本语法:
${运算表达式}
-
关系运算
-
逻辑运算
-
算术运算
应用实例
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>el运算符</title> </head> <body> <h1>el运算符</h1> <% request.setAttribute("num1", 90); request.setAttribute("num2", 30); %> num1+num2=${num1+num2}<br/> num1>num2?=${num1>num2}<br/> </body> </html>

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" %> <html> <head> <title>el empty的运算</title> </head> <body> <% 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}<br/> k2是否为空=${empty k2}<br/> k3是否为空=${empty k3}<br/> k4是否为空=${empty k4}<br/> k5是否为空=${empty k5}<br/> </body> </html>

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" %> <html> <head> <title>演示el的四个常用的隐含对象(域对象)</title> </head> <body> <h2>演示el的四个常用的隐含对象(域对象)</h2> <% request.setAttribute("k1", "request-k1数据"); pageContext.setAttribute("k1", "pageContext-k1数据"); session.setAttribute("k1", "session-k1数据"); application.setAttribute("k1", "application-k1数据"); %> <h3>1.jsp脚本方式获取</h3> <%=request.getAttribute("k1")%> <h3>2.el方式来获取域对象的数据</h3> request域中的k1=${requestScope.k1}<br/> pageContext域中的k1=${pageScope.k1}<br/> session域中的k1=${sessionScope.k1}<br/> application域中的k1=${applicationScope.k1}<br/> </body> </html>

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" %> <html> <head> <title>pageContext 对象的使用</title> </head> <body> <h1>pageContext 对象的使用</h1> <%-- //通过 request 对象来获取和 HTTP 协议相关的数据 request.getScheme() 它可以获取请求的协议 request.getServerName() 获取请求的服务器 ip 或域名 request.getServerPort() 获取请求的服务器端口号 getContextPath() 获取当前工程路径 request.getMethod() 获取请求的方式(GET 或 POST) request.getRemoteHost() 获取客户端的 ip 地址 session.getId() 获取会话的唯一标识 --%> <hr/> 协议: ${ pageContext.request.scheme }<br> 服务器 ip:${ pageContext.request.serverName }<br> 服务器端口:${ pageContext.request.serverPort }<br> 工程路径:${ pageContext.request.contextPath }<br> 请求方法:${ pageContext.request.method }<br> 客户端 ip 地址:${ pageContext.request.remoteHost }<br> 会话 id :${ pageContext.session.id }<br> <h3>使用 jsp 表达式脚本获取如上信息</h3> ip 地址: <%=request.getRemoteHost() %><br> 会话 id :<%=request.getRequestedSessionId()%><br> ... <h3>使用 el 表达式形式获取信息-简化写法</h3> <% //可以将request对象放到pageContext属性中,通过key可以很方便地取出,从而简化写法 pageContext.setAttribute("req", request); %> ip 地址: ${req.remoteHost} <br> 获取请求方法: ${req.method} <br> 客户端 ip 地址:${ req.remoteHost }<br> ... </body> </html>

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" %> <html> <head> <title>jstl的快速入门</title> </head> <body> <h1>jstl的快速入门</h1> <%-- 1.c: if ...标签类似 2.if(10>2){ out.println("xxx") } --%> <c:if test="${10>2}"> <h2>10>2成立~~~</h2> </c:if> </body> </html>

12.3core核心库
12.3.1<c:set />标签
例子:<c:set scope="request" var="k1" value="v1"/>
<c:set/>
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" %> <html> <head> <title>c:set标签的使用</title> </head> <body> <h1>c:set标签的使用</h1> <% //原来的写法 //request.setAttribute("email","tomas@qq.com"); %> <%--jstl的写法--%> <c:set scope="request" var="name" value="tomas"> </c:set> <%--c:set-name的值:${name} 或者--%> c:set-name的值:${requestScope.name} </body> </html>

12.3.2<c:if />标签
例子:<c:if test="10>2">hello< /c:if>
<c:if />
- if标签用来做if判断
- test属性表示判断的条件(用EL表达式输出)
例子
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>c:if标签使用</title> </head> <body> <h2>c:if标签使用</h2> <c:set scope="request" var="num1" value="20"/> <c:set scope="request" var="num2" value="10"/> <c:if test="${num1>num2}"> <h3>${num1}>${num2}</h3> </c:if> </body> </html>

12.3.3<c:choose >标签
介绍:多路判断。跟switch...case...default非常接近
例子
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>c:choose标签的使用</title> </head> <body> <% 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} <hr> <h1>c:choose标签的使用</h1> <c:choose> <c:when test="${requestScope.scope > 80}"> <h3>${scope}-成绩优秀!</h3> </c:when> <c:when test="${requestScope.scope > 60}"> <h3>${scope}-成绩及格!</h3> </c:when> <c:otherwise> <h3>${scope}-成绩不及格,继续努力!</h3> </c:otherwise> </c:choose> </body> </html>

12.3.4<c:forEach />标签
介绍: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" %> <html> <head> <title>c:forEach标签</title> </head> <body> <h1>c:forEach标签</h1> <hr> <h2>第一种遍历方式:从i到j</h2> <ul> <%-- 1.遍历1到5 2.begin属性设置开始的索引,end属性设置结束的索引 3.var属性表示循环的变量(也就是当前正在遍历到的数据) 4.等价于 for(int i = 1; i < = 5; i++){} 5.默认情况情况下,i的值每次会递增 1 6.可以使用step属性来设置增量 --%> <c:forEach begin="1" end="5" var="i"> <li>排名=${i}</li> </c:forEach> </ul> <hr> <h2>第二种遍历方式:遍历数组</h2> <% request.setAttribute("sports", new String[]{"打篮球", "乒乓球"}); %> <%-- 1.item属性指定要遍历的集合/数组 2.var 自定义变量,每次取出的数据会存放到该变量中 3.等价于 for(Object item:arr){} 相当于每循环一次,就在items指定的数组中, 取出一个数据存放到var自定义的变量中, 直至取完数据就退出循环 --%> <c:forEach items="${requestScope.sports}" var="sp"> 运动名称=${sp}<br/> </c:forEach> <hr> <h2>第三种遍历方式:遍历Map</h2> <% HashMap<String, Object> 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:取出值 --%> <c:forEach items="${requestScope.cities}" var="city"> 城市信息=${city.key}--${city.value}<br/> </c:forEach> <hr> <h2>第四种遍历方式:遍历List</h2> <% ArrayList<Monster> 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 等属性值 --%> <c:forEach items="${requestScope.monsters}" var="monster"> 妖怪信息=${monster.id}-${monster.name}-${monster.skill}<br/> </c:forEach> </body> </html>

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" %> <html> <head> <title>query</title> </head> <body> <h1>查询妖怪</h1> <form action="/jsp/queryServlet" method="post"> 请输入查询的最低工资:<input type="text" name="sal"/><br/><br/> <input type="submit" value="点击查询"/> </form> </body> </html>
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<Monster> 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<Monster> 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" %> <html> <head> <title>view</title> </head> <body> <h1>显示妖怪信息</h1> <table border="1px" width="300px"> <tr> <td>id</td> <td>name</td> <td>job</td> <td>sal</td> </tr> <c:forEach items="${requestScope.vaildMonsters}" var="monster"> <tr> <td>${monster.id}</td> <td>${monster.name}</td> <td>${monster.skill}</td> <td>${monster.sal}</td> </tr> </c:forEach> </table> </body> </html>

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!