JSP、EL 表达式、JSTL



JSP 介绍

JSP 简介

JSP 全称是 Java Server Page,它和 Servlet 一样,也是 Sun 公司推出的一套开发动态 web 资源的技术,称为 JSP/Servlet 规范。

JSP 的本质其实就是一个 Servlet。

JSP 与 Servlet 的区别

  1. JSP 经编译后就变成了 Servlet(JSP 的本质就是 Servlet,JVM 只能识别 Java 的类,不能识别 JSP 的代码,于是 Web 容器将 JSP 的代码编译成 JVM 能够识别的 Java类)。

  2. Servlet 和 JSP 最主要的不同点在于:Servlet 的应用逻辑在 Java 文件中,并且完全从表示层中的 HTML 里分离开来。而对于 JSP,Java 和 HTML 可以组合成一个扩展名为 .jsp 的文件。

  3. JSP 是 Servlet 的一种简化,使用 JSP 只需要完成输出到客户端的内容(JSP 中的 Java 脚本如何镶嵌到一个类中,由 JSP 容器完成);而 Servlet 则是个完整的 Java 类,这个类的 service() 方法用于生成对客户端的响应。

  4. JSP 更擅长于页面显示(视图),Servlet 更擅长于逻辑控制。

  5. Servlet 中没有内置对象,JSP 中的内置对象都必须通过 HttpServletRequest 对象、 HttpServletResponse 对象以及 HttpServlet 对象得到。

JSP、HTML、Servlet 适用场景

类别 适用场景
HTML 只能开发静态资源,不能包含 java 代码,无法添加动态数据。
Servlet 写 java 代码,可以输出页面内容,但是不够方便,开发效率低。
JSP 包括了 HTML 的展示技术,同时具备 Servlet 输出动态资源的能力;但是不适合作为控制器来用。

JSP 简单入门

1. 创建 JavaWeb 工程:

image

2. 在 index.jsp 中编写内容:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>JSP的入门</title>
  </head>
  <body>
      这是第一个JSP页面
  </body>
</html>

3. 测试运行:

image

JSP 执行详解

JSP 就是一个特殊的 Servlet,其执行过程如下:

  1. 客户端提交请求;
  2. Tomcat 服务器解析请求地址;
  3. 找到 JSP 页面;
  4. Tomcat 将 JSP 页面翻译成 Servlet 的 java 文件;
  5. 将翻译好的 .java 文件编译成 .class 文件;
  6. 返回到客户端浏览器上。

JSP 的 .java 文件内容分析

当我们打开 index.jsp 翻译的 java 文件看到的就是public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase类的声明,接着我们在 Tomcat 的源码中找到该类的声明,如下图:

image

该图表明我们写的 JSP 的本质就是一个 HttpServlet。

image

同时,我们在 index_jsp.java 文件中找到了输出页面的代码,并且在浏览器端查看源文件,看到的内容是一样的。这也就是说明,我们的浏览器上的内容,在通过 JSP 展示时,本质都是用 out.write() 输出出来的。

至此,我们应该清楚地认识到,JSP 是一个特殊的 Servlet,主要是用于展示动态数据。它展示的方式是用流把数据输出。而我们在使用 JSP 时,涉及的 HTML 部分,都与 HTML 的用法一致,这部分称为 JSP 中的模板元素,在开发过程中,先写好这些模板元素,因为它们决定了页面的外观。


JSP 语法

1)Java 代码块

在 JSP 中,可以使用 java 脚本代码,形式为:<% 此处写java代码 %>

但是在实际开发中,极少使用此种形式编写 java 代码。同时需要注意的是:

<%
	在里面写java程序脚本,需要注意:这里面的内容由tomcat负责翻译,翻译之后是service方法的成员变量
%>

示例:

<!--Java代码块-->
<% out.println("这是Java代码块");%>
<hr/>

2)JSP 表达式

在 JSP 中,可以使用特定表达式语法,形式为:<%=表达式%>

JSP 在翻译完后是out.print(表达式内容);,所以<%out.print("当前时间);%><%="当前时间"%>是等价的。

在实际开发中,这种表达式语法用的也很少。

示例:

<!--JSP表达式-->
<%="这是JSP表达式"%><br/>
就相当于<br/>
<%out.println("这是没有JSP表达式输出的");%>

3)JSP 声明

在 JSP 中也可以声明一些变量、方法、静态方法,形式为:<%! 声明的内容 %>

使用 JSP 声明时需要注意:

<%! 
	需要注意的是:写在里面的内容将会被tomcat翻译成全局的属性或者类方法
%>                                    

示例:

<!--JSP声明-->
<%! String str = "声明语法格式";%>
<%=str%>

4)JSP 注释

在使用 JSP 时,它也有自己的注释,形式为:<%--注释--%>

需要注意的是:

  • 在 JSP 中可以使用 HTML 的注释,但是只能注释 HTML 元素,不能注释 Java 程序片段和表达式。同时,被 HTML 注释部分会参与翻译,并且会在浏览器上显示。

  • JSP 的注释不仅可以注释 Java 程序片段,也可以注释 HTML 元素,并且被 JSP 注释的部分不会参与翻译成 .java 文件,也不会在浏览器上显示。

示例:

<%--JSP注释--%>
<!--HTML注释-->

5)语法示例

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JSP语法</title>
</head>
<body>

<!--Java代码块-->
<% out.println("这是Java代码块");%>
<hr/>

<!--JSP表达式-->
<%="这是JSP表达式"%><br/>
就相当于<br/>
<%out.println("这是没有JSP表达式输出的");%>

<hr/>
<!--JSP声明-->
<%! String str = "声明语法格式";%>
<%=str%>

<hr/>

<%--JSP注释--%>
<!--HTML注释-->

</body>
</html>

JSP 语法运行结果:

image


JSP 指令

1)page 指令

language:告知引擎,脚本使用的是 Java。默认是 Java,不写也行。

extends:告知引擎,JSP 对应的 Servlet 的父类是哪个,不需要写,也不需要改。

import:告知引擎,导入哪些包(类)。

注意:引擎会自动导入:java.lang.*, javax.servlet.*, javax.servlet.http.*, javax.servlet.jsp.*

导入的语法:

<%@pageimport=”java.util.Date, java.util.UUID”%>

或者:

<%@pageimport=”java.util.Date”%>
<%@pageimport=”java.util.UUID”%>

Eclipse 自动导入:Alt + /

session:告知引擎是否产生 HttpSession 对象,即是否在代码中调用 request.getSession()。默认是 true。

buffer:JspWriter 用于输出 JSP 内容到页面上。告知引擎,设定他的缓存大小。默认 8kb。

errorPage:告知引擎,当前页面出现异常后,应该转发到哪个页面上(路径写法:/代表当前应用)。

  • 当在 errorPage 上使用了 isErrorPage=true 之后,IE8 有时候不能正常显示。
  • 配置全局错误页面:web.xml。
  • 当使用了全局错误页面,就无须再写 errorPage 来实现转到错误页面,而是由服务器负责跳转到错误页面。
<error-page>    
    <exception-type>java.lang.Exception</exception-type>    			
    <location>/error.jsp</location>
</error-page>

<error-page>
    <error-code>404</error-code>
    <location>/404.html</location>
</error-page>     

isErrorPage:告知引擎,是否抓住异常。如果该属性为 true,页面中就可以使用 exception 对象,打印异常的详细信息。默认值是 false。

contentType:告知引擎,响应正文的 MIME 类型。

  • contentType="text/html;charset=UTF-8" 相当于 response.setContentType("text/html;charset=UTF-8");

pageEncoding:告知引擎,翻译 JSP 时(从磁盘上读取 JSP 文件)所用的码表。

  • pageEncoding="UTF-8" 相当于告知引擎用 UTF-8 读取 JSP 。

isELIgnored:告知引擎,是否忽略 EL 表达式,默认值是 false,不忽略。

2)include 指令

语法:<%@include file="" %>,该指令表示包含外部页面。

  • file 属性以/开头,表示当前应用。

使用示例

image

静态包含 .java 文件内容

image

3)taglib 指令

语法<%taglib uri="" prefix=""%>

作用:该指令用于引入外部标签库(html 标签和 jsp 标签无需引入)。

属性:

  • uri:外部标签的 URI 地址。
  • prefix:使用标签时的前缀。

JSP 对象

九大隐式对象

什么是隐式对象呢?它指的是在 JSP 中,可以不声明就直接使用的对象。它只存在于 JSP 中,因为 Java 类中的变量必须要先声明再使用。

其实 JSP 中的隐式对象也并非是未声明,只是它是在翻译成 .java 文件时声明的,所以我们可以在 JSP 中直接使用。

隐式对象名称 类型 备注
request javax.servlet.http.HttpServletRequest
response javax.servlet.http.HttpServletResponse
session javax.servlet.http.HttpSession page 指令可以控制开关
application javax.servlet.ServletContext
page Java.lang.Object 当前 JSP 对应的 servlet 引用实例
config javax.servlet.ServletConfig
exception java.lang.Throwable page 指令可以控制开关
out javax.servlet.jsp.JspWriter 字符输出流,相当于 printwriter
pageContext javax.servlet.jsp.PageContext 重要

ageContext 对象

简介:

它是 JSP 独有的对象,Servlet 中没有这个对象。

ageContext 本身也是一个域(作用范围)对象,但是它可以操作其他 3 个域对象中的属性,而且还可以获取其他 8 个隐式对象。

生命周期:

它是一个局部变量,所以它的生命周期随着 JSP 的创建而开始,随着 JSP 的结束而消失。每个 JSP 页面都有一个独立的 PageContext。

常用方法

image

四大域对象

域对象名称 范围 级别 备注
PageContext 页面范围 最小,只能在当前页面用 因范围太小,开发使用较少
ServletRequest 请求范围 一次请求或当前请求转发用 当请求转发之后,再次转发时请求域丢失。开发使用较多
HttpSession 会话范围 多次请求数据共享时使用 多次请求共享数据,但不同的客户端不能共享。。如存放用户的登录信息、购物车功能。开发使用较多
ServletContext 应用范围 最大,整个应用都可以使用 因范围太大,尽量少用。如果对数据有修改则需要做同步处理

JSP 最佳使用场景:MVC 模型

MVC 模型:

  • M(model,模型):通常用于封装数据模型(实体类)。

  • V(view,视图):通常用于展示数据。动态展示用 JSP 页面,静态数据展示用 HTML。

    • JSP 擅长显示界面,不擅长处理程序逻辑。在 Web 开发中多用于展示动态界面。
  • C(controller,控制器):通常用于处理请求和响应。一般指的是 Servlet。

    • Servlet 擅长处理业务逻辑,不擅长输出显示界面。在 Web 开发中多用于控制程序逻辑(流程)。

image

JSP 综合案例

1)登录功能

index.jsp:主页

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
</head>
<body>
    <%--
        获取会话域的数据
        如果获取到了,则显示添加和查询功能
        如果获取不到,则显示登录功能
    --%>
    <% Object username = session.getAttribute("username");
            if(username == null || "".equals(username)){
    %>
            <a href="/web_demo/login.jsp">登录<a/>
    <%}else { %>
            <a href="/web_demo/add.jsp">添加<a/>
            <a href="/web_demo/queryServlet">查询<a/>
    <% } %>
</body>
</html>

login.jsp:登录页

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录页</title>
</head>
<body>
    <form action="/web_demo/loginServlet" method="get" autocomplete="off">
        姓名:<input type="text" name="username"><br/>
        密码:<input type="password" name="password"><br/>
        <button type="submit">登录</button>
    </form>
</body>
</html>

LoginServlet:获取登录页的用户名和密码

package com.demo;

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

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取用户名和密码
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        // 校验用户名密码
        // 用户名为空
        if("".equals(username) || username == null){
            // 重定向到登录页
            resp.sendRedirect("/web_demo/login.jsp");
        } else {
            // 用户名不为空,存入会话域数据
            req.getSession().setAttribute("username", username);
            // 重定向到首页
            resp.sendRedirect("/web_demo/index.jsp");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

2)添加功能

add.jsp:实现添加学生信息的表单项

<%--
  Created by IntelliJ IDEA.
  User: juno
  Date: 2021/10/7
  Time: 21:18
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>添加页</title>
</head>
<body>
    <form action="/web_demo/addServlet" method="get" autocomplete="off">
        学生姓名:<input type="text" name="username"><br/>
        学生年龄:<input type="number" name="age"><br/>
        学生成绩:<input type="number" name="score"><br/>
        <button type="submit">保存</button>
    </form>
</body>
</html>

AddServlet:获取学生信息并保存到文件中

package com.demo;

import com.demo.bean.Student;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

@WebServlet("/addServlet")
public class AddServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取表单数据
        String username = req.getParameter("username");
        String age = req.getParameter("age");
        String score = req.getParameter("score");

        // 创建学生对象并赋值
        Student student = new Student();
        student.setAge(age);
        student.setScore(score);
        student.setUsername(username);

        // 将新增数据写入文件中
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("d://student.txt", true));
        bufferedWriter.write(username+","+age+","+score);
        bufferedWriter.newLine();
        bufferedWriter.close();

        // 通过定时刷新功能响应给浏览器
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().write("添加成功!2秒后自动跳转到首页~");
        resp.setHeader("Refresh", "2;URL=/web_demo/index.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

3)查看功能

QueryServlet:读取文件中的学生信息到集合中

package com.demo;

import com.demo.bean.Student;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

@WebServlet("/queryServlet")
public class QueryServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 创建字符输入流对象,关联读取的文件
        BufferedReader bufferedReader = new BufferedReader(new FileReader("d://student.txt"));

        // 创建集合对象,用于保存student对象
        ArrayList<Student> arrayList = new ArrayList<>();

        // 循环读取文件中的数据,将数据封装到Student对象中。再把多个学生对象添加到集合中
        String line;
        while((line = bufferedReader.readLine()) != null){
            Student student = new Student();
            String[] attribute = line.split(",");
            student.setUsername(attribute[0]);
            student.setAge(attribute[1]);
            student.setScore(attribute[2]);
            arrayList.add(student);
        }

        // 将集合对象存入会话域中
        req.getSession().setAttribute("students", arrayList);

        // 重定向到学生列表页面
        resp.sendRedirect("/web_demo/query.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

query.jsp:展示学生信息列表

<%--
  Created by IntelliJ IDEA.
  User: juno
  Date: 2021/10/7
  Time: 23:41
  To change this template use File | Settings | File Templates.
--%>
<%@ page import="com.demo.bean.Student" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>学生列表页</title>
</head>
<body>
  <table width="600px" border="1px">
    <tr>
      <th>学生姓名</th>
      <th>学生年龄</th>
      <th>学生成绩</th>
    </tr>
      <% ArrayList<Student> students = (ArrayList<Student>) session.getAttribute("students");
          for(Student student: students){
      %>
          <tr align="center">
            <td><%= student.getUsername() %></td>
            <td><%= student.getAge() %></td>
            <td><%= student.getScore() %></td>
          <tr/>
      <%  } %>
  </table>
</body>
</html>

页面效果如下:

image


EL 表达式

EL 表达式介绍

基本概念:

EL 表达式,全称是 Expression Language,意为表达式语言。它是 Servlet 规范中的一部分,是 JSP2.0 规范加入的内容。

其作用是用于在 JSP 页面中获取数据,从而让我们的 JSP 脱离 Java 代码块和 JSP 表达式。

基本语法:

EL 表达式的语法格式非常简单:${表达式内容}

假定我们在请求域中存入了一个名称为 "message" 的数据,此时在 JSP 中获取的方式如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>EL表达式入门案例</title>
  </head>
  <body>
    <%--使用java代码在请求域中存入一个名称为message的数据--%>
    <% request.setAttribute("message","Expression Language"); %>

    Java代码块获取:<% out.print(request.getAttribute("message")); %>
    <br/>
    JSP表达式获取:<%= request.getAttribute("message") %>
    <br/>
    EL表达式获取:${message}
  </body>
</html>

可以看出,有多种方式可以从请求域中获取数据,但是 EL 表达式写起来是最简单的方式。这也是以后我们在实际开发中,当使用 JSP 作为视图时,绝大多数都会采用的方式。

EL 表达式注意事项

EL 表达式没有空指针异常、没有数组下标越界、没有字符串拼接。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>EL表达式的注意事项</title>
  </head>
  <body>
    <%-- EL表达式的三个没有 --%>
    第一个:没有空指针异常<br/>
    <% String str = null;
       request.setAttribute("testNull",str);
    %>
    ${testNull}
    <hr/>
    第二个:没有数组下标越界<br/>
    <% String[] strs = new String[]{"a","b","c"};
       request.setAttribute("strs",strs);
    %>
    取第一个元素:${strs[0]}<br/>
    取第六个元素:${strs[5]}
    <hr/>
    第三个:没有字符串拼接<br/>
    <%--${strs[0]+strs[1]}--%>
    ${strs[0]}+${strs[1]}
  </body>
</html>

运行效果:

image

EL 表达式的数据来源

EL 表达式只能从四大域中获取数据,调用的就是findAttribute(name,value);方法,通过名称根据范围由小到大逐个域中查找,找到就返回,找不到就什么都不显示。

它可以获取对象,可以是对象中关联的其他对象,可以是一个 List 集合,也可以是一个 Map 集合。

使用:创建两个实体类(User 和 Address)并使用 EL 表达式获取输出

  • User 实体类:
public class User implements Serializable{

    private String name = "黑马";
    private int age = 18;
    private Address address = new Address();
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }    
}
  • Address 实体类:
public class Address implements Serializable {

    private String province = "北京";
    private String city = "昌平区";

    public String getProvince() {
        return province;
    }
    public void setProvince(String province) {
        this.province = province;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
}
  • JSP:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="com.itheima.domain.User" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title>EL入门</title>
    </head>
    <body>
        <%--
            EL表达式的数据获取:
                它只能在四大域对象中获取数据,不在四大域对象中的数据它取不到。
                它的获取方式就是findAttribute(String name)
         --%>
         
         <br/>-----------获取对象数据---------------------<br/>
         <% //1.把用户信息存入域中
             User user = new User();
             pageContext.setAttribute("u", user);
          %>
          ${u}===============输出的是内存地址 <%--相当于调用 <%=pageContext.findAttribute("u")%> --%><br/>
          ${u.name} <%--相当于调用 <% User user = (User) pageContext.findAttribute("u");out.print(user.getName());%> --%><br/>
          ${u.age}
         
         <br/>-----------获取关联对象数据------------------<br/>
         ${u.address}==========输出的address对象的地址<br/>
         ${u.address.province}${u.address.city}<br/>
         ${u["address"]['province']}
         
         <br/>-----------获取数组数据---------------------<br/>
         <% String[] strs = new String[]{"He", "llo", "Expression", "Language"}; 
             pageContext.setAttribute("strs", strs);
         %>
         ${strs[0]}==========取的数组中下标为0的元素<br/>
         ${strs[3]}
         ${strs[5]}===========如果超过了数组的下标,则什么都不显示<br/>
         ${strs["2"]}=========会自动为我们转换成下标<br/>
         ${strs['1']}
         
         <br/>-----------获取List集合数据-----------------<br/>
         <% List<String> list = new ArrayList<String>();
             list.add("AAA");
             list.add("BBB");
             list.add("CCC");
             list.add("DDD");
             pageContext.setAttribute("list", list);
          %>
         ${list}<br/>
         ${list[0]}<br/>
         ${list[3]}<br/>
         
         <br/>-----------获取Map集合数据------------------<br/>
         <% Map<String,User> map = new HashMap<String,User>();
             map.put("aaa", new User());
             pageContext.setAttribute("map", map);
          %>
          ${map}<br/>
          ${map.aaa} <%--获取map的value,是通过get(Key) --%> <br/>
          ${map.aaa.name}${map.aaa.age}<br/>
          ${map["aaa"].name}
    </body>
</html>

运行效果:

image

EL 表达式运算符

image

有两个特殊的运算符,使用方式如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="com.itheima.domain.User" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title>EL两个特殊的运算符</title>
    </head>
    <body>
        <%-- empty运算符:
             它会判断:对象是否为null,字符串是否为空字符串,集合中元素是否是0个
        --%>
        <% String str = null;
          String str1 = "";
          List<String> slist = new ArrayList<String>();
          pageContext.setAttribute("str", str);
          pageContext.setAttribute("str1", str1);
          pageContext.setAttribute("slist", slist);
        %>
        ${empty str}============当对象为null返回true<br/>
        ${empty str1}==========当字符串为空字符串是返回true(注意:它不会调用trim()方法)<br>
        ${empty slist}==========当集合中的元素是0个时,是true
        <hr/>
			
        <%-- 三元运算符: 
             条件?真:假  
        --%>
        <% request.setAttribute("gender", "female"); %>
        <input type="radio" name="gender" value="male" ${gender eq "male"?"checked":""} >男
        <input type="radio" name="gender" value="female" ${gender eq "female"?"checked":""}>女
    </body>
</html>

运行效果:

image

EL 表达式的 11 个隐式对象

EL表达式除了能在四大域中获取数据,同时也为我们提供了隐式对象,可以让我们无需声明而直接使用,并且可以访问对象有返回值的方法。

11 个对象见下表(需要注意的是,它和 JSP 的隐式对象不是一回事):

EL 中的隐式对象 类型 对应的 JSP 隐式对象 备注
PageContext Javax.serlvet.jsp.PageContext PageContext 完全一样
ApplicationScope Java.util.Map 没有 应用域范围的对象数据
SessionScope Java.util.Map 没有 会话域范围的对象数据
RequestScope Java.util.Map 没有 请求域范围的对象数据
PageScope Java.util.Map 没有 页面域范围的对象数据
Header Java.util.Map 没有 请求消息头 key,值是 value(一个)
HeaderValues Java.util.Map 没有 请求消息头 key,值是数组(一个头多个值)
Param Java.util.Map 没有 请求参数 key,值是 value(一个)
ParamValues Java.util.Map 没有 请求参数 key,值是数组(一个名称多个值)
InitParam Java.util.Map 没有 全局参数,key 是参数名称,value 是参数值
Cookie Java.util.Map 没有 Key 是 cookie 的名称,value 是 cookie 对象

示例:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>EL表达式11个隐式对象</title>
</head>
<body>

    <%-- applicationScope sessionScope requestScope pageScope 操作四大域对象中的数据 --%>
    <%--获取四大域对象中的数据--%>
    <%
       pageContext.setAttribute("username", "zhangsan");
       request.setAttribute("username", "zhangsan");
       session.setAttribute("username", "zhangsan");
       application.setAttribute("username", "zhangsan");
    %>
    ${username} <br>
    ${requestScope.username} <br>

    <%-- pageContext对象 可以获取其他三个域对象和JSP中八个隐式对象 --%>
    <%-- 获取虚拟目录名称 --%>
    ${pageContext.request.contextPath} <%-- 等价于 <%= request.getContextPath() %> --%>

    <%-- header headerValues  获取请求头数据 --%>
    ${header["connection"]} <br>
    ${headerValues["connection"][0]} <br>

    <%-- param paramValues 获取请求参数数据 --%>
    ${param.username} <br>
    ${paramValues.hobby[0]} <br>
    ${paramValues.hobby[1]} <br>

    <%-- initParam 获取全局配置参数 --%>
    ${initParam["pname"]}  <br>

    <%-- cookie 获取cookie信息 --%>
    ${cookie}  <br>  <%-- 获取Map集合 --%>
    ${cookie.JSESSIONID}  <br> <%-- 获取map集合中第二个元素 --%>
    ${cookie.JSESSIONID.name}  <br> <%-- 获取cookie对象的名称 --%>
    ${cookie.JSESSIONID.value} <%-- 获取cookie对象的值 --%>

</body>
</html>

JSTL

JSTL 介绍

JSTL 的全称是 JSP Standard Tag Libary,是 JSP 中标准的标签库。

JSTP 是由 Apache 实现的,由以下 5 个部分组成:

组成 作用 说明
Core 核心标签库 通用逻辑处理
Fmt 国际化相关 需要不同地域显示不同语言时使用
Functions EL 函数 EL 表达式可以使用的方法
SQL 操作数据库 很少用
XML 操作XML 很少用

使用要求:

要想使用 JSTL 标签库,需要先在 javaweb 工程中需要导入坐标。首先是要在工程的 WEB-INF 目录中创建一个 lib 目录,然后把 JSTL 的 jar 拷贝到 lib 目录中,再在 jar 包上点击右键,然后选择【Add as Libary】添加。如下图所示:

image

核心标签库

在实际开发中,用到的 JSTL 标签库主要以核心标签库为准,偶尔会用到国际化标签库的标签。

下表中把经常可能用到的标签列在此处,其余标签库可自行查阅:

标签名称 功能分类 分类 作用
<c:if> 流程控制 核心标签库 用于条件判断
<c:choose>
<c:when>
<c:otherwise>
流程控制 核心标签库 用于多个条件判断
<c:foreache> 迭代操作 核心标签库 用于循环遍历

JSTL 使用

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%-- 导入jstl标签库 --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>JSTL的常用标签</title>
  </head>
  <body>
  
    <%-- 演示 c:if --%>
    <% pageContext.setAttribute("score", "F"); %>
    <c:if test="${pageScope.score eq 'A'}">
        优秀
    </c:if>
    <c:if    test="${pageScope.score eq 'C'}">
        一般
    </c:if>
    <hr/>
    
    <%-- 演示 c:choose c:when c:otherwise --%>
    <c:choose>
        <c:when test="${pageScope.score eq 'A'}">
            AAA
        </c:when>
        <c:when test="${pageScope.score eq 'B'}">BBB
        </c:when>
        <c:when test="${pageScope.score eq 'C'}">CCC
        </c:when>
        <c:when test="${pageScope.score eq 'D'}">DDD
        </c:when>
        <c:otherwise>其他</c:otherwise>
    </c:choose>
    
    <%-- 演示 c:forEach 它是用来遍历集合的
         属性:
             items:要遍历的集合,它可以是EL表达式取出来的
             var:把当前遍历的元素放入指定的page域中。 var的取值就是key,当前遍历的元素就是value
                 注意:它不能支持EL表达式,只能是字符串常量
             begin:开始遍历的索引
             end:结束遍历的索引
             step:步长。i+=step
             varStatus:它是一个计数器对象。里面有两个属性,一个是用于记录索引。一个是用于计数。
                        索引是从0开始。计数是从1开始
    --%>
    <hr/>
    
    <% List<String> list = new ArrayList<String>();
       list.add("AAA");
       list.add("BBB");
       list.add("CCC");
       list.add("DDD");
       list.add("EEE");
       list.add("FFF");
       list.add("GGG");
       list.add("HHH");
       list.add("III");
       list.add("JJJ");
       list.add("KKK");
       list.add("LLL");
       pageContext.setAttribute("list",list);
     %>
     
    <c:forEach items="${list}" var="s" begin="1" end="7" step="2">
        ${s}<br/>
    </c:forEach>
    
    <hr/>
    
    <c:forEach begin="1" end="9" var="num">
        <a href="#">${num}</a>
    </c:forEach>
    <hr/>
    <table>
        <tr>
            <td>索引</td>
            <td>序号</td>
            <td>信息</td>
        </tr>

    <c:forEach items="${list}" var="s" varStatus="vs">
        <tr>
            <td>${vs.index}</td>
            <td>${vs.count}</td>
            <td>${s}</td>
        </tr>
    </c:forEach>

    </table>
  </body>
</html>
posted @ 2021-10-08 00:11  Juno3550  阅读(180)  评论(0编辑  收藏  举报