• day24-服务器端渲染技术02


    服务器端渲染技术02

    11.EL表达式

    11.1EL表达式介绍

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

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

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

    4. 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}
    image-20221126175436250

    注意:

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

    2. jsp脚本在输出null时,输出的是 “null” 字符串

    image-20221126175619276

    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"]}
    image-20221126183418404

    11.4EL运算操作符

    EL的运算操作符和java基础的操作符在概念和用法上都是一样的,只是形式上有些变化。

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

    2. 关系运算

      image-20221126184648121
    3. 逻辑运算

      image-20221126184716846
    4. 算术运算

      image-20221126184741241

    应用实例

    <%@ 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}
    image-20221126185358669

    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" %>
    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}
    image-20221126190307314

    11.6EL的三元运算

    1. 表达式1?表达式2:表达式3

    2. 如果表达式1的值为真,返回表达式2的值,反之返回表达式3的值

      image-20221126190610775

    11.7EL的11个隐含/内置对象

    image-20221126190833117

    下面以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}
    image-20221126192219036

    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() 获取会话的唯一标识

    例子

    image-20221126192927968
    <%@ 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 }
    ...
    image-20221126193731450

    12.JSTL

    12.1JSTL介绍

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

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

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

      image-20221126194224976

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

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

      image-20221126195131691

    12.2快速入门

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

      image-20221126195318622
    2. 在jsp页面的引入标签,要放在文件第一行

      image-20221126195629830
    3. 导入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>
    image-20221126200823058

    12.3core核心库

    12.3.1标签

    例子:

    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" %>
    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}
    image-20221126203603115

    12.3.2标签

    例子:hello< /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" %>
    c:<span class="hljs-keyword">if</span>标签使用

    c:if标签使用

    "request" var="num1" value="20"/>
    "request" var="num2" value="10"/>
    if test="${num1>num2}">

    ${num1}>${num2}

    if>
    image-20221126204707838

    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}-成绩不及格,继续努力!

    image-20221126210844648

    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.遍历15
      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}
      image-20221126215316493

      13.练习

      需求分析:使用jsp+servlet+jstl+el完成查询-显示案例,需求如下:

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

      image-20221126215708667 image-20221126215721462

      练习

      思路:通过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

      查询妖怪

      "/jsp/queryServlet" method="post">
      请输入查询的最低工资:"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}
      image
    • 相关阅读:
      如何做好测试用例设计
      k8s中的Controller
      vben admin BasicTable 表格的基本使用
      dolphinscheduler添加hana支持
      @Reference 、@Resource和@Autowired的简单区分
      SpringSecurity系列——授权与认证概述,安全架构day2-2(源于官网5.7.2版本)
      从零开始打造一款基于SpringBoot+SpringCloud的后台权限管理系统
      Codeforces Round #726 (Div. 2) E1. Erase and Extend (Easy Version)
      SpringCloud 之 服务提供者
      语义分割 Semantic Segmentation
    • 原文地址:https://www.cnblogs.com/liyuelian/p/16928697.html