JavaWeb-05-JSP规范-06-EL表达式

JavaWeb-05-JSP规范-06-EL表达式

1.JSP的繁琐之处

当使用JSP将作用域对象中存放的数据写入到响应体时,

按传统的方式实现共有三步:

  1. 在执行标记中通过java代码从作用域对象中读取数据
  2. 完成数据类型转化
  3. 在输出标记中将转换后的数据写入响应体内
<%
    String value = (String)request.getAttribute("key1");
%>
<%=value%>

这在企业级开发中是非常繁琐的。

为了降低使用JSP文件开发时Java命令开发强度,EL表达式诞生了。

2.EL表达式概述

2.1EL工具包

  • 由Java技术开发的一个jar包
  • 作用:降低JSP文件开发时Java命令开发强度
  • Tomcat服务器本身自带了EL工具包(Tomcat安装地址/lib/el-api.jar)

EL表达式是EL工具包提供的一种特殊命令格式【表达式命令格式】。

2.2EL命令格式

${作用域对象别名.共享数据key名}

2.3EL命令作用

EL表达式用于JSP文件中,负责从作用域对象读取指定的共享数据并输出到响应体。

3.EL表达式中作用域对象的别名

3.1JSP文件中可以使用的作用域对象

作用域对象类型 作用域对象 描述
ServletContext application 全局作用域对象
HttpSession session 会话作用域对象
HttpServletRequest request 请求作用域对象
PageContext pageContext 当前页作用域对象

其中,当前页作用域对象【pageContext】是JSP文件独有的作用域对象,Servlet中不存在当前页作用域对象。

在pageContext中存放的共享数据仅能在当前JSP文件中使用,不能共享给其他Servlet或其他JSP文件。

在真实开发过程中,主要用于JSTL标签与JSP文件间的数据共享。

		数据
JSTL------------>pageContext------------>JSP

3.2EL表达式中作用域对象的别名

EL表达式为了区分,提供了作用域对象别名。

作用域对象 在EL中的别名
application $
session $
request $
pageContext $

4.演示EL表达式的使用

4.1演示流程

  1. 新建一个网站【MyWeb】,创建一个Servlet接口实现类【OneServlet】和一个JSP文件【test.jsp】
  2. 在OneServlet中分别向全局作用域对象、会话作用域对象、请求作用域对象中添加共享数据。
  3. 在test.jsp中读取三个作用域对象中的共享数据并写入到响应体中。

OneServlet:

package com.tsccg.controller;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @Author: TSCCG
 * @Date: 2021/08/24 21:19
 */
public class OneServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String userName = "张三";
        Integer age = 20;
        String sex = "男";
        //全局作用域对象
        ServletContext application = request.getServletContext();
        application.setAttribute("userName",userName);
        //会话作用域对象
        HttpSession session = request.getSession();
        session.setAttribute("age",age);
        //请求作用域对象
        request.setAttribute("sex",sex);
        //通过请求转发向服务器申请调用test.jsp
        request.getRequestDispatcher("/test.jsp").forward(request,response);
    }
}

4.2使用传统方式实现

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--1.传统方式--%>
<%--1.1读取作用域对象中的共享数据--%>
<%
    String userName = (String)application.getAttribute("userName");
    Integer age = (Integer)session.getAttribute("age");
    String sex = (String)request.getAttribute("sex");
%>
<%--1.2将共享数据写入响应体--%>
姓名:<%=userName%>
<br>
年龄:<%=age%>
<br>
性别:<%=sex%>

4.4使用EL表达式实现

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--2.EL表达式--%>
姓名:${applicationScope.userName}<br>
年龄:${sessionScope.age}<br>
性别:${requestScope.sex}

5.使用EL表达式将引用对象类型属性写入响应体

5.1命令格式

${作用域对象别名.引用对象名.引用对象属性名}

注意:引用对象属性名一定要和引用类型的属性名完全一致,包括大小写。

5.2命令作用

从作用域对象中读取指定共享数据所关联的引用对象的属性值,并自动将属性值写入到响应体里。

注意:EL表达式没有提供遍历集合的方法,所以无法从作用域对象中读取集合的内容并输出。

5.3演示将引用对象类型属性写入响应体

5.3.1演示流程

创建一个Student类、一个Servlet接口实现类【TwoServlet】和一个JSP文件【test2.jsp】。

  1. Student类有两个私有属性【Integer id,String name】,提供Getter和Setter方法。
  2. 在TwoServlet中创建一个Student实例对象并写入数据,然后将实例对象写入请求作用域中。然后通过请求转发方式向Tomcat申请调用test2.jsp文件。
  3. 在test2.jsp中分别使用传统方法和EL表达式读取实例对象中的属性并写入响应体内。

5.3.2编写Student

package com.tsccg.entity;

/**
 * @Author: TSCCG
 * @Date: 2021/08/24 22:33
 */
public class Student {
    private Integer id;
    private String name;

    public Student() {
    }

    public Student(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    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;
    }
}

5.3.3编写TwoServlet

package com.tsccg.controller;

import com.tsccg.entity.Student;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Author: TSCCG
 * @Date: 2021/08/24 22:32
 */
public class TwoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Student student = new Student(1,"张三");
        request.setAttribute("student",student);
        request.getRequestDispatcher("/test2.jsp").forward(request,response);
    }
}

5.3.4编写test2.jsp

<%@ page import="com.tsccg.entity.Student" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--1.传统方式--%>
<%
    //1.1读取请求作用域中的共享数据,获得引用对象
    Student student = (Student)request.getAttribute("student");
%>
<%--1.2调用get方法获得引用对象属性值并写入响应体--%>
学生ID:<%=student.getId()%>
<br>
学生姓名:<%=student.getName()%>

<hr>

<%--2.EL表达式--%>
学生ID:${requestScope.student.id}
<br>
学生姓名:${requestScope.student.name}

5.3.5查看结果

6.EL表达式简化版

6.1演示简化版表达式的使用

6.1.1格式

为了进一步降低开发难度,可以将EL表达式标准版中的作用域对象别名省去。

${共享数据名}

6.1.2实例演示

OneServlet

public class OneServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.向当前全局作用域对象中添加一个共享数据
        ServletContext application = request.getServletContext();
        application.setAttribute("key1","张三");
        //2.请求转发调用one.jsp
        request.getRequestDispatcher("/one.jsp").forward(request,response);
    }
}

one.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
标准版EL表达式输出作用域对象中key1的值:${applicationScope.key1}
<hr>
简化版EL表达式输出作用域对象中key1的值:${key1}

结果:

6.2简化版表达式存在隐患

6.2.1演示简化版EL表达式从不同作用域对象中定位同名数据

当我们再向会话作用域对象session中添加一个共享数据:

OneServlet

public class OneServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.向当前全局作用域对象中添加一个共享数据,共享数据名为【key1】
        ServletContext application = request.getServletContext();
        application.setAttribute("key1","张三");
        //2.向当前会话作用域对象中添加一个共享数据,共享数据名仍为【key1】,但值不同
        HttpSession session = request.getSession();
        session.setAttribute("key1","李四");
        //请求转发调用one.jsp
        request.getRequestDispatcher("/one.jsp").forward(request,response);
    }
}

one.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
标准版EL表达式输出全局作用域对象中key1的值:${applicationScope.key1}<br/>
标准版EL表达式输出会话作用域对象中key1的值:${sessionScope.key1}
<hr>
简化版EL表达式输出作用域对象中key1的值:${key1}<br/>
简化版EL表达式输出作用域对象中key1的值:${key1}

结果:

6.2.2简化版EL表达式工作原理

EL表达式简化版因为没有指定作用域对象,所以在执行时采用【猜】算法。

EL表达式简化版定位共享数据过程:

  1. 首先在【pageContext】定位共享数据
    1. 如果存在则直接读取并输出然后结束执行
    2. 如果不存在则去【request】中定位共享数据
      1. 如果存在则直接读取并输出然后结束执行
      2. 如果不存在则去【session】中定位共享数据
        1. 如果存在则直接读取并输出然后结束执行
        2. 如果不存在则去【application】中定位共享数据
          1. 如果存在则直接读取并输出然后结束执行
          2. 如果不存在则返回null

定位顺序:

pageContext------>request------>session------>application

6.2.3简化版EL表达式的隐患

简化版EL表达式执行时,需要从多个作用域对象中按顺序定位共享数据,因此存在隐患:

  1. 容易降低程序执行速度
  2. 容易导致数据定位错误

6.3简化版EL表达式的应用场景

简化版EL表达式最初的设计目的,就是为了简化从【pageContext】中读取共享数据并输出的难度。

尽管简化版EL表达式存在诸多隐患,但在实际开发中,开发人员为了节省时间,一般都使用简化版,拒绝使用标准版。

7.EL表达式支持运算表达式

7.1前提

在JSP文件中,有时需要将读取的共享数据进行运算后,再将运算结果写入到响应体。

同样,EL表达式也能够计算共享数据。

7.2支持的运算表达式

运算表达式类型 常用符号
数学运算 加减乘除(+ - * /)
关系运算 (> < == >= <= !=)或(gt lt eq ge le !=)
逻辑运算 与、或、非(&& || !)

7.3使用EL表达式演示数学运算

OneServlet

public class OneServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //在当前请求作用域对象中添加一个字符串和一个数字
        String num1 = "100";
        Integer num2 = 500;
        request.setAttribute("num1",num1);
        request.setAttribute("num2",num2);
        //请求转发调用one.jsp
        request.getRequestDispatcher("one.jsp").forward(request,response);
    }
}

one.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--使用传统java代码计算结果--%>
<%
    String value1 = (String)request.getAttribute("num1");
    Integer value2 = (Integer)request.getAttribute("num2");
    int sum = Integer.parseInt(value1) + value2;
%>
使用传统的java命令计算输出的结果:<%=sum%>

<hr>

使用EL表达式计算输出的结果:${num1+num2}

结果:

7.4使用EL表达式演示关系运算

TwoServlet

public class TwoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Integer age = 19;
        request.setAttribute("age",age);
        request.getRequestDispatcher("two.jsp").forward(request,response);
    }
}

two.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--使用传统java方式实现关系运算输出--%>
<%
    Integer age = (Integer)request.getAttribute("age");
    if (age >= 18) {
%>
        欢迎光临<br>
<%
    } else {
%>
        谢绝入内<br>
<%
    }
%>
<hr>
<%--使用EL表达式实现关系运算输出--%>
EL表达式:${age>=18?"欢迎光临":"谢绝入内"}

结果:

8.EL表达式内置对象

8.1内置对象1:param

处理:http://localhost:8080/MyWeb/one.jsp?userName=Tom&passWord=123

8.1.1命令格式

${param.请求参数名}

8.1.2命令作用

通过请求对象读取当前请求头中的请求参数内容,并将请求参数内容写入到响应体。

8.1.3代替命令

<%
    String userName = request.getParameter("userName");
    String passWord = request.getParameter("passWord");
%>
userName:<%=userName%><br>
passWord:<%=passWord%>

8.1.4使用EL表达式内置对象param演示读取输出请求头中的参数

one.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--传统java方式获取请求头中请求参数参数--%>
<%--http://localhost:8080/MyWeb/one.jsp?userName=Tom&passWord=123--%>
<%
    String userName = request.getParameter("userName");
    String passWord = request.getParameter("passWord");
%>
传统java方式读取输出请求参数:<br>
userName:<%=userName%><br>
passWord:<%=passWord%>

<hr>

<%--使用EL表达式--%>
EL表达式读取输出请求参数:<br>
userName:${param.userName}<br>
passWord:${param.passWord}

结果:

8.2内置对象2:paramValues

8.2.1命令格式

${paramValues.请求参数名[下标]}

8.2.2命令作用

如果浏览器发送的请求参数是一个请求参数并且这个参数关联多个值,那么就可以通过paramValues读取请求参数下指定位置的值,并写入到响应体。

处理:http://localhost:8080/MyWeb/two.jsp?pageNo=1&pageNo=2&pageNo=3

此时pageNo请求参数在请求包中以数组的形式存在:

pageNo[1,2,3]

8.2.3代替命令

<%
	String[] array = request.getParameterValues("pageNo");
%>
第一个值:<%=array[0]%>//1
第二个值:<%=array[1]%>//2

8.2.4使用EL表达式内置对象paramValues演示读取输出请求头中的参数

two.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

第一个值:${paramValues.pageNo[0]}<br>
第二个值:${paramValues.pageNo[1]}<br>
第三个值:${paramValues.pageNo[2]}

结果:

posted @ 2021-08-24 23:06  TSCCG  阅读(123)  评论(0编辑  收藏  举报