服务器端渲染技术02

11.EL表达式

11.1EL表达式介绍

  1. EL表达式全称:Expression Language,是表达式语言

  2. EL表达式主要是代替jsp页面的表达式脚本

  3. EL表达式输出数据时,比jsp的表达式脚本简洁

  4. EL表达式基本语法:${key}

    底层其实走的还是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>

注意:

  1. EL表达式在输出null时,输出的是空串""

  2. 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基础的操作符在概念和用法上都是一样的,只是形式上有些变化。

  1. 基本语法:${运算表达式}

  2. 关系运算

  3. 逻辑运算

  4. 算术运算

应用实例

<%@ 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运算

  1. empty运算可以判断一个数是否为空,如果为空,返回true,否则返回false
  2. 以下几种情况为空:
    • 值为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. 表达式1?表达式2:表达式3

  2. 如果表达式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协议相关的数据:

    1. request.getScheme() 它可以获取请求的协议
    2. request.getServerName() 获取请求的服务器 ip 或域名
    3. request.getServerPort() 获取请求的服务器端口号
    4. getContextPath() 获取当前工程路径
    5. request.getMethod() 获取请求的方式(GET 或 POST)
    6. request.getRemoteHost() 获取客户端的 ip 地址
    7. 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介绍

  1. JSTL(Java server pages standarded tag library,即JSP标准标签库。

  2. EL表达式是为了替换jsp中的表达式脚本,JSTL是为了替换代码脚本<%%>,这样可以使jsp页面变得更加简洁。

  3. JSTL由五个标签库组成:

  4. 使用JSTL,需要导入相关的jar包:

    下载连接:https://tomcat.apache.org/download-taglibs.cgi

12.2快速入门

  1. 将两个jar包直接复制粘贴到web应用程序的WEB-INF\lib目录下,add as library

  1. 在jsp页面的引入标签,要放在文件第一行

  1. 导入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标签可以往域中保存数据

  1. 等价于 域对象.setAttribute(key,value);
  2. scope 属性设置保存到哪个域
    • page表示PageContext域(默认值)
    • request表示Request域
    • session表示Session域
    • application表示ServletContext域
  3. var 属性设置 key 是什么
  4. 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 />

  1. if标签用来做if判断
  2. 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完成查询-显示案例,需求如下:

  1. 点击超链接,可以显示所有的妖怪信息
  2. 要求显示的数据在servlet中准备,并放入到request域对象中
  3. 扩展,如果要求增加根据薪水sal条件过滤,怎么处理?

练习

思路:

day24-服务器端渲染技术02的更多相关文章

  1. 基于React服务器端渲染的博客系统

    系统目录及源码由此进入 目录 1. 开发前准备 1.1 技术选型1.2 整体设计1.3 构建开发 2. 技术点 2.1 react2.2 redux, react-router2.3 server-r ...

  2. 服务器端渲染VS浏览器端渲染

    1)浏览器渲染和服务器渲染区别:何为渲染?如果我们只是想显示一堆不变的数据,那么我们直接写一个a.html丢到服务器上让客户端访问就可以了.但这是基本不可能的事情,数据一般是变化的.你不可能为每套数据 ...

  3. 细说后端模板渲染、客户端渲染、node 中间层、服务器端渲染(ssr)

    细说后端模板渲染.客户端渲染.node 中间层.服务器端渲染(ssr) 前端与后端渲染方式的发展大致经历了这样几个阶段:后端模板渲染.客户端渲染.node 中间层.服务器端渲染(ssr). 1. 后端 ...

  4. react实现ssr服务器端渲染总结和案例(实例)

    1.什么是 SSR SSR 是 server side render 的缩写,从字面上就可以理解 在服务器端渲染,那渲染什么呢,很显然渲染现在框架中的前后端分离所创建的虚拟 DOM 2.为什么要实现服 ...

  5. React服务器端渲染框架next.js项目实战及部署上下文context问题解决办法

    在前段时间折腾过搭建react服务器端项目架构,点击这里了解下,正好最近有个重构PC网站的需求,考虑SEO等因素.在做技术选型的时候决定采用nextjs.项目开发过程中,nextjs的体验非常棒,个人 ...

  6. React 服务器端渲染流程

    其实我们在访问客户端渲染的页面时,请求到的只是一个 html 空壳,里面引入了一个 js 文件,所有的内容都是通过 js 进行插入的,正是因为页面是由 js 渲染出来的,所以会带来如下几个问题: 1. ...

  7. Unity酱~ 卡通渲染技术分析(二)

    前面的话 上一篇Unity酱~ 卡通渲染技术分析(一) 写了CharaMain.cginc,服装的渲染是怎么实现的.这篇来分析一下头发跟皮肤的实现 头发 本来以为unitychan的头发会有各向异性的 ...

  8. 服务端渲染技术NUXT

    什么是服务端渲染 ​ 服务端渲染又称SSR (Server Side Render),是在服务端完成页面的内容,而不是在客户端通过AJAX获取数据. 服务器端渲染(SSR)的优势主要在于:更好的 SE ...

  9. 【大前端之前后分离01】JS前端渲染VS服务器端渲染

    前言 之前看了一篇文章:@Charlie.Zheng Web系统开发构架再思考-前后端的完全分离,文中论述了为何要前后分离,站在前端的角度来看,是很有必要的:但是如何说服团队使用前端渲染方案却是一个现 ...

  10. React服务器端渲染值Next.js

    昨天leader给分配了新任务,让熟悉一下ssr,刚开始有点懵,啥玩意?百度了一下,不就是服务器端渲染(server side render,简称: ssr). ssr简介 服务端渲染一个很常见的场景 ...

随机推荐

  1. 使用Steamwork.Net 接入Steam一点心得

    1.  前言 这是我在开发过程中使用的一点总结,目前使用的东西包含基础登录功能,存档功能,成就系统,以及DLC安装功能.Steamwork不仅仅有这些功能还有游戏内交易,排行榜,数据传输等功能,这些功 ...

  2. Lua 支持虚函数的解决方案

    概述 lua本身没有提供类似C++虚函数机制,调用的父类方法调用虚函数可能会出现问题. 问题分析 分析这段代码和输出 local Gun = {} -- 示例,实际应用还要考虑构造,虚表等情况 fun ...

  3. [开源福利] FreeRedis 历时两年正式发布 v1.0 [C#.NET Redis Client]

    最近很多 .net QQ 群无故被封停,特别是 wpf 群几乎全军覆没.依乐祝的 .net6交流群,晓晨的 .net跨平台交流群,导致很多码友流离失所无家可归,借此机会使用一次召唤术,有需要的请加群: ...

  4. 以TrueType为例谈字形描述

    以TrueType为例谈字形描述 作者:哲思 时间:2022.9.17 邮箱:zhe__si@163.com GitHub:zhe-si (哲思) (github.com) 一.前言 在深入理解&qu ...

  5. windows下 Rust 环境配置

    搭建 Visual Studio Code 开发环境 首先,需要安装最新版的 Rust 编译工具和 Visual Studio Code. Rust 编译工具:https://www.rust-lan ...

  6. Django 之必知必会三板斧

    一.HttpResponse 在django.http 模块中定义了HttpResponse 对象的API,HttpRequest 对象由Django 自动创建,不调用模板,直接返回数据. 1 在 a ...

  7. 静态文件:Static Files

    官方文档地址:https://fastapi.tiangolo.com/zh/tutorial/static-files/ from fastapi import FastAPI from fasta ...

  8. AlertManager 之微信告警模板,UTC时间错8个小时的解决办法

    注意事项: alertmanager中的web页面显示的报警时间是UTC时间,错8个小时,企业微信报警模板中已经修改过来了 下面配置可以作为参考: 1.prometheus操作 1.1 配置告警规则, ...

  9. Leetcode栈&队列

    Leetcode栈&队列 232.用栈实现队列 题干: 思路: 栈是FILO,队列是FIFO,所以如果要用栈实现队列,目的就是要栈实现一个FIFO的特性. 具体实现方法可以理解为,准备两个栈, ...

  10. 洛谷P4304 TJOI2013 攻击装置 (二分图匹配)

    题目大意:一个矩阵,一些点被拿掉,在棋盘上马走日,马之间不能落在同一点,求最多放几匹马. 采用对矩阵黑白染色,画个图可以发现:马可以走到的位置和他所处的位置颜色不同,将马和他可以走到的位置连边,最多可 ...