- JSP指令、JSP九大内置对象、EL表达式
6.JSP深入
6.1 JSP指令
指令的作用:指导 JSP 翻译引擎如何工作(指导当前的 JSP 翻译引擎如何翻译 JSP 文件)。
指令包括哪些呢?
include
指令:包含指令,在 JSP 中完成静态包含,很少用了(这里不讲)。taglib
指令:引入标签库的指令,这个到 JSTL 标签库的时候再学习,现在先不管。page
指令:目前重点学习 page 指令。
指令的使用语法是什么?
<%@指令名 属性名=属性值 属性名=属性值 属性名=属性值......%>
关于 page 指令当中都有哪些常用的属性呢?
<%@page session="true|false" %> true表示启用JSP的内置对象session,表示一定启动session对象。没有session对象会创建。 如果没有设置,默认值就是session="true" session="false" 表示不启动内置对象session。当前JSP页面中无法使用内置对象session。
1
2
3
4
5
6
7
8
- ```jsp
<%@page contentType="text/json" %>
contentType属性用来设置响应的内容类型
但同时也可以设置字符集。
默认 text/html
设置字符集为UTF-8:
<%@page contentType="text/json;charset=UTF-8" %><%@page import="java.util.List, java.util.Date, java.util.ArrayList" %> <%@page import="java.util.*" %> import语句,导包。
1
2
3
4
5
- ```jsp
<%@page errorPage="/error.jsp" %>
当前页面出现异常之后,跳转到error.jsp页面。
errorPage属性用来指定出错之后的跳转位置。<%@page isErrorPage="true" %> 表示启用JSP九大内置对象之一:exception 默认值是false。 为true表示当前配置的error页面可以使用异常对象exception,用exception.printStackTrace();来打印错误信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
```jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isErrorPage="true" %>
<html>
<head>
<title>error page</title>
</head>
<body>
<h1>发生错误!</h1>
<%
exception.printStackTrace();
%>
</body>
</html>
6.2 JSP九大内置对象
四个域对象:
jakarta.servlet.jsp.PageContext pageContext
(页面作用域)jakarta.servlet.http.HttpServletRequest request
(请求作用域,一次请求可以跨多页页面)jakarta.servlet.http.HttpSession session
(会话作用域)jakarta.servlet.ServletContext application
(应用作用域)- pageContext < request < session < application 。
- 以上四个作用域都有:
setAttribute
、getAttribute
、removeAttribute
方法。 - 以上作用域的使用原则:尽可能使用小的域。
jakarta.servlet.ServletConfig config
java.lang.Throwable exception
(异常对象)java.lang.Object page
(其实是 this,指当前的 servlet 对象)负责输出响应
jakarta.servlet.jsp.JspWriter out
(负责输出)jakarta.servlet.http.HttpServletResponse response
(负责响应)
6.3 EL表达式
EL 表达式是干什么用的?
- Expression Language(表达式语言)
- EL 表达式可以代替 JSP 中的 java 代码,让 JSP 文件中的程序看起来更加整洁,美观。
- JSP 中夹杂着各种 java 代码,例如
<% java代码 %>
、<%=%>
等,导致 JSP 文件很混乱,不好看,不好维护。所以才有了后期的 EL 表达式。
- JSP 中夹杂着各种 java 代码,例如
- EL 表达式可以算是 JSP 语法的一部分,EL 表达式归属于 JSP。
EL 表达式出现在 JSP 中主要是:
- 从某个作用域中取数据,然后将其转换成字符串,然后将其输出到浏览器。这就是 EL 表达式的功效。
- 第一功效:从某个域中取数据。
- 四个域:
- pageContext
- request
- session
- application
- 四个域:
- 第二功效:将取出的数据转成字符串。
- 如果是一个 java 对象,也会自动调用 java 对象的
toString
方法将其转换成字符串。
- 如果是一个 java 对象,也会自动调用 java 对象的
- 第三功效:将字符串输出到浏览器。
- 和这个一样:
<%= %>
,将字符串输出到浏览器。
- 和这个一样:
- 第一功效:从某个域中取数据。
EL 表达式用于取数据,然后在页面进行数据的展示。
- 从某个作用域中取数据,然后将其转换成字符串,然后将其输出到浏览器。这就是 EL 表达式的功效。
6.3.1 EL表达式语法
EL 表达式很好用,基本的语法格式:
${表达式}
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<%"text/html;charset=UTF-8" %> contentType=
<%
// 向request作用域当中存储username为zhangsan
request.setAttribute("username", "zhangsan");
request.setAttribute("obj", new Object());
%>
<%--将request域当中的数据取出来,并且还要输出到浏览器,使用java代码怎么办?--%>
<%=request.getAttribute("username")%>
<br>
<%=request.getAttribute("obj")%>
<br>
<hr>
<%--使用EL表达式呢?--%>
${username}
<br>
${obj}
6.3.2 EL表达式的使用
1 | <% |
注意:如果对四个域中的几个都存了 User 对象,例如:
pageContext.setAttribute("userObj", user1)
request.setAttribute("userObj", user2)
session.setAttribute("userObj", user3)
application.setAttribute("userObj", user4)
则在没有指定范围的情况下,EL 表达式优先从小范围中读取数据。即
${userObj}
会优先取出 pageContext 中的user1
对象。EL 表达式中有四个隐含的隐式的范围:
pageScope
对应的是pageContext
范围。requestScope
对应的是request
范围。sessionScope
对应的是session
范围。applicationScope
对应的是application
范围。
如果**要从指定的域中取数据,需要按如下语法取:
${范围.数据名}
**。- 例如
${requestScope.userObj}
会取出 request 中的user2
对象。
EL 表达式取数据的时候有两种形式:
第一种:
.
(大部分使用这种方式)第二种:
[ ]
(如果存储到域的时候,这个 name 中含有特殊字符,可以使用 [ ])request.setAttribute("abc.def", "zhangsan");
${requestScope.abc.def}
这样是无法取值的。
应该这样:
${requestScope["abc.def"]}
EL 表达式对 null 进行了预处理。如果是 null,则向浏览器输出一个空字符串。
${userObj}
这个 EL 表达式等同于这一段 java 代码:<%=request.getAttribute("userObj") == null ? "" : request.getAttribute("userObj")%>
${abc}
和${"abc"}
的区别是什么?${abc}
表示从某个域中取出数据,并且被取的这个数据的 name 是 “abc”,之前一定有这样的代码:域.setAttribute("abc", 对象);
${"abc"}
表示直接将 “abc” 当做普通字符串输出到浏览器,不会从某个域中取数据了。
${userObj}
底层是怎么做的?- 从域中取数据,取出 user 对象;然后调用 user 对象的
toString
方法,转换成字符串;最终输出到浏览器。
如果想输出对象的属性值,怎么办?
1
2
3
4
5
6
7
8
9
10
11
12<%--如果想输出对象的属性值,怎么办?--%>
${userObj.username} 使用这个语法的前提是:User对象有getUsername()方法。
${userObj.password} 使用这个语法的前提是:User对象有getPassword()方法。
${userObj.age} 使用这个语法的前提是:User对象有getAge()方法。
${userObj.email} 使用这个语法的前提是:User对象有getEmail()方法。
没有对应的属性,有对应的get方法不会报错
EL表达式中的 “.” 这个语法,实际上调用了底层的getXxx()方法。
注意:如果没有对应的get方法,则出现异常。报500错误。
${userObj.addr222.zipcode}
以上EL表达式对应的java代码:
user.getAddr222().getZipcode()注意:在 EL 表达式中,
${user.email}
和 User 对象有没有 email 属性并没有太大关系,只要 User 类中有getEmail
方法,${user.email}
就会表示为该方法的返回值。另一种写法是${user["email"]}
。- 可以简单的理解为,
${user.email}
就是${user.getEmail()}
的缩写。
- 可以简单的理解为,
6.3.3 从Map集合中取数据
${map.key}
1 | <%@ page import="java.util.HashMap" %> |
6.3.4 从数组和List集合中取数据
${数组[index]}
1 | <%@ page import="com.f.javaweb.jsp.bean.User" %> |
6.3.5 EL表达式其他细节
page 指令当中,有一个属性,可以忽略 EL 表达式:
1
2
3
4
5
6
7<%"text/html;charset=UTF-8" isELIgnored="true" %> contentType=
isELIgnored="true" 表示忽略EL表达式,整个EL表达式会被当成一个字符串输出在浏览器
isELIgnored="false" 表示不忽略EL表达式。(这是默认值)
isELIgnored="true" 这个是全局的控制。整个JSP页面的EL表达式
可以使用反斜杠进行局部控制:\${username} 这样也可以忽略EL表达式。通过 EL 表达式获取应用的根:
${pageContext.request.contextPath}
pageContext.getRequest()
可以获取 request 对象。在 EL 表达式当中没有 request 这个隐式对象,requestScope 这个只代表“请求范围”,不等同于 request 对象。
在 EL 表达式当中有一个隐式的对象:pageContext。EL 表达式中的 pageContext 和 JSP 中的九大内置对象 pageContext 是同一个对象。
EL 表达式中其他的隐式对象:
- pageContext
- param,用于获取只有一个值的请求参数
- paramValues,用于获取有多个值的请求参数
- initParam,用于获取 Servlet 上下文请求参数,在
ServletContext
中 - 其他…
1 | <%"text/html;charset=UTF-8" %> contentType= |
1 |
|
6.3.6 EL表达式的运算符
- EL 表达式的运算符有以下几种:
- 算术运算符
- +、-、*、/、%
- 关系运算符
- ==、!=、>、>=、<、<=
- 逻辑运算符
- !、&&、||
- 条件运算符
? :
- 取值运算符
[ ]
、.
empty
运算符empty
运算符的结果是 boolean 类型
- 算术运算符
1 | <%@ page import="com.f.javaweb.jsp.bean.Student" %> |