JSP、EL表达式、JSTL

JSP、EL表达式、JSTL

JSP

JSP 概念和原理

JSP,Java Server Pages,即 Java 服务器端页面,可以理解为是一种特殊的页面,其中既可以书写 HTML 标签内容,又可以写 Java 代码,JSP 可以简化书写,例如在之前的案例中,如果想通过 Servlet 对 HTML 的展示内容作出修改,必须在输出流中书写 HTML 标签和内容,这无疑是非常复杂的。

JSP 的本质就是一个 Servlet,当客户端访问一个 JSP 资源时,服务器会解析该请求,找到是否有该 JSP 资源,如果有,服务器会将该 JSP 转换为 .java 文件,编译该 .java 文件生成 .class 字节码文件,然后虚拟机加载字节码文件进内存,由该类(一个 Servlet)提供访问,其中所有 HTML 标签内容都会由该类通过输出流写入页面。

JSP 定义 Java 代码

JSP 中有三种方式定义 Java 代码

  1. <% java代码 %>,使用该脚本定义的代码相当于 service() 方法中的代码,service() 方法中可以定义什么,该脚本中就可以定义什么
  2. <%! java代码 %>,使用该脚本定义的代码转换后会出现在 Java 类成员的位置
  3. <%= java代码 %>,使用该脚本定义的代码转换后会输出到页面上,也就是相当于输出语句中的内容

JSP 指令

JSP 指令写在 JSP 页面最上方,用于配置 JSP 页面和导入资源文件,格式为 <%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ... %>

常用指令

  1. page 用于配置页面

    1. contentType,等同于 response.setContentType(),设置响应体的 MIME 类型和字符集
    2. import 导包
    3. errorPage 表示如果,当前页面发生异常,会自动跳转到指定的错误页面
    4. isErrorPage 标识当前页面是否是错误页面,如果是错误页面才可以使用内置对象 exception

    例如

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
  1. include 用于导入其他 JSP 页面资源,例如
<%@include file="top.jsp"%>
  1. taglib 导入资源

    1. prefix 自定义的前缀
    2. uri 资源的路径

    例如,导入 JSTL 标准标签库

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

JSP 的内置对象

所谓内置对象,就是在 JSP 中无需创建或获取,可以直接使用的对象,共 9 个

变量名真实类型作用
pageContextPageContext当前页面共享数据,获取其他 8 个内置对象
requestHttpServletRequest一次请求(转发)中共享数据
sessionHttpSession一次会话中共享数据
applicationServletContext所有用户间共享数据
responseHttpServletResponseHttp 响应对象
pageObject当前页面(Servlet)对象,相当于 this
outJspWriter将数据输出到页面上,类似 response.getWriter()
configServletConfigServlet 的配置对象
exceptionThrowable异常对象

注意 response.getWriter().write()out.write() 的区别:在 Tomcat 服务器真正给客户端做出响应之前,会先找 response 缓冲区数据,再找out 缓冲区数据,也就是说无论 response.getWriter().write()out.write() 两条语句在 JSP 中定义的位置如和,response.getWriter().write() 数据输出永远在 out.write() 之前

EL 表达式

概念

EL,Expression Language,即表达式语言,用于替换和简化 JSP 页面中的 Java 代码的编写。一条 EL 的语法格式为 ${ 表达式 },JSP 默认支持 EL,EL 前加 \ 进行转义则可以忽略该 EL 表达式,让页面将其当做普通文本输出

EL 的基本运算

EL 支持最基本的算术运算符、比较运算符、逻辑运算符(与或非),用法与 Java 类似,不再赘述,同时还有一个特殊的空运算符 empty,用于判断数组、字符串、集合对象是否为 null 或者长度为 0,如果要取反,使用 not empty 即可,例如 ${empty list} 表示 list 是否为 null 或长度为 0,${not empty str} 表示 str 是否不为 null 且长度大于 0

EL 获取值

  • EL 表达式只能获取值,而不能改写或者调用对象的方法

  • EL 表达式默认只能从域对象中获取值,其基本语法为 ${域名称.键名},即从指定域中获取指定键的值

    域名称JSP内置对象
    pageScopepageContext
    requestScoperequest
    sessionScopesession
    applcationScopeapplication (ServletContext)

    例如,在 request 域中存储了键值对 name=zhangsan,要获取该值,使用表达式 ${requestScope.name} 即可,还有一种简单写法 ${键名},也就是省略域名称,表示一次从最小的域中查找是否有该键,直到找到为止

  • 获取对象的属性值
    使用 ${域名称.键名.属性名},这里的本质是调用对象的 getter 方法,注意对象属性和字段(成员变量)的区别

  • 获取 List 集合的元素
    使用 ${域名称.键名[索引]}

  • 获取 Map 集合中的元素
    使用 ${域名称.键名.map_key} 或者 ${域名称.键名[map_key]}

  • 获取 JSP 内置对象
    EL 中的隐式对象 pageContext 即 JSP 的 pageContext,可以用来获取 JSP 其他内置对象,例如,常用的动态获取项目虚拟目录功能(用于填写提交表单的路径或者 <a> 标签的 href),${pageContext.request.contextPath}

JSTL

JSTL,Java Server Pages Tag Library,即 JSP 标准标签库,是由 Apache 组织提供的开源的免费的 JSP 标签,用于简化和替换 JSP 页面上的 Java 代码

要使用 JSTL 首先要在项目导入 JSTL 相关 jar 包,然后使用 taglib 指令在 JSP 页面头部引入标签库,<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

常用标签

  1. if 标签:相当于 Java 的 if 语句
    • test 属性,是必须属性,接受一个布尔表达式,如果表达式为 true,则显示标签体内容,否则不显示,所以一般来说 test 属性会配合 EL 表达式一起使用
  2. choose 标签,相当于 Java 的 switch 语句
    • 使用 when 标签作判断,相当于 case
    • 使用 otherwise 标签做其他情况的声明,相当于 default
      例如,现在 request 域有一个键值对 request.setAttribute("num",3),使用 choose 标签展示对应的信息
    <c:choose>
        <c:when test="${requestScope.number == 1}"> 星期一 </c:when>
        <c:when test="${requestScope.number == 2}"> 星期二 </c:when>
        <c:when test="${requestScope.number == 3}"> 星期三 </c:when>
        <c:when test="${requestScope.number == 4}"> 星期四 </c:when>
        <c:when test="${requestScope.number == 5}"> 星期五 </c:when>
        <c:when test="${requestScope.number == 6}"> 星期六 </c:when>
        <c:when test="${requestScope.number == 7}"> 星期天 </c:when>
        <c:otherwise> 输入有误 </c:otherwise>
    </c:choose>
    
  3. foreach 标签,相当于 Java 的增强 for 循环
    • items 属性,表示要遍历的字符串、List、Map 等容器
    • var 属性,表示临时变量
    • begin 属性,表示循环遍历的初始值
    • end 属性,表示循环遍历的结束值
    • step 属性,表示循环遍历的临时变量的增长步长
    • varStatus 属性,表示循环状态
      • index 子属性,表示本次迭代从 0 开始的索引
      • count 子属性,表示本次迭代从 1 开始的次数
        例如,现在 request 域有一个 List 集合 request.setAttribute("list",list),使用 foreach 标签动态展示集合中的数据到表格中,list 中存储 User 实体类的对象
    <c:forEach items="${requestScope.list}" var="user" varStatus="s">
        <tr>
            <td>${s.count}</td>
            <td>${user.name}</td>
            <td>${user.age}</td>
        </tr>
    </c:forEach>
    

参考

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://yzt.cool/archives/jspel表达式jstl