目录
8. EL表达式(Expression Language )
jsp项目的结构
lib是在web/WEB_INF中
使用servlet或者jsp时都要导入javaee-api-7.0.jar
1.什么是JSP
JSP
全名为
Java Server Pages
,中⽂名叫
java服务器⻚⾯
,其根本是⼀个简化的
Servlet
设计。
在
HTML
⽂件
中
插⼊Java程序段和JSP标记
(tag)
,从⽽形成JSP⽂件
。
⽤
JSP
开发的
Web
应⽤是
跨平台的
,既能在
Linux
下运⾏,也能在其他操作系统上运⾏。
JSP将⽹⻚逻辑与⽹⻚设计的显示分离,没有JSP之前是在sevlet中通过out实现页面动态展示,又要负责处理用户请求,又要负责向用户展示请求结果,就出现JSP来分担一部分业务,从编译角度,jsp还是servlet,是.jsp结尾的特殊的servlet,而原来的servlet是java文件,
*.html 静态⻚⾯
(
包含固定的⻚⾯内容
)
*.jsp
动态⻚⾯
(
⻚⾯数据可以动态更新
,
⽀持嵌套
java
代码和
html
代码
)
jsp=html+java
2. JSP为什么会出现
1.servlet
展示信息的不⽅便,引⼊了
JSP
。
2.JSP
本质上也是⼀个
servlet
3.JSP
就是在
HTML
⻚⾯中嵌⼊了
java
代码。
3.JSP中如何嵌套java代码
⼩脚本(<% java代码%>)
声明标签
<%!
变量或者⽅法声明
%>
表达式标签
<%=
表达式
%>
在⻚⾯上显示的效果
程序代码标签
<%java
代码
%>
⻚⾯上动态展示内容
<body>
<%! int i=10;%><!--成员变量-->
<%! public void show(){}%> <!--成员⽅法-->
<%=i%> <!--输出变量值-->
</body>
<body>
<!--声明变量-->
<%
int a=10;
int b=20;
%>
<!--获取值-->
a+b=<%=a+b%>
<!--定义方法-->
<%!
public void test(){
System.out.println("test");
}
%>
<!--调用方法-->
<%
test();
%>
</body>
page指令:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
jsp中的注释
<!-- html
注释内容
,
查看源码时能看到
-->
<%-- jsp
注释
,
查看⻚⾯源码时看不到
--%>
4. JSP的原理
当浏览器访问jsp文件
。服务器发现后缀为
.jsp
,它会根据路径找到 index.jsp⽂件,会将
index.jsp
翻译成
index_jsp.java
⽂件,对这个
java
⽂件进⾏编译,产⽣⼀个index_jsp.class⽂件,将
class
⽂件加载运⾏。将
JSP
翻译成
java
⽂件,它是将
JSP
中的所有的
HTML
代码通过流进⾏输出,也就是说最终翻译成class
,被虚拟机加载,它本质是
servlet
,它就会往回响应,响应回去就是把JSP
中的
HTML
代码以流的⽅式写回浏览器。所以在
JSP
中展示出了
HTML
代码
5. JSP的内置对象
JSP
中⼀共预先定义了
9
个这样的对象,分别为:
request
、
response
、
session
、application、page、pagecontext、out、 config、
exception
1、request对象
request
对象是
javax.servlet.
httpServletRequest类型的对象
。 该对象代表了
客户端的请求信息
,主要⽤于接受
通过HTTP协议传送到服务器的数据
。(包括头信息、系统信息、请求⽅式以及请求参数等)。request
对象的
作⽤域为⼀次请求
。
2、response对象
response 对象是HttpServletResponse类型的对象,代表的是
对客户端的响应
,主要是将
JSP
容器处理过的对象传回到客户端。
response 对象也具有
作⽤域,它只在JSP⻚⾯内有效
。所属类型
:HttpServletResponse
3、session对象
session 对象是
由服务器⾃动创建的与⽤户请求相关的对象
。服务器
为每个⽤户都⽣成⼀个session对象,⽤于保存该⽤户的信息,跟踪⽤户的操作状态
。
session
对象
内部使⽤Map类来保存数据
,因此保存数据的格式为 “Key/value”
。
session
对象的
value
可以使复杂的对象类型,⽽不仅仅局限于字符串类型。HttpSession
4、application对象
application
对象可将信息保存在服务器中,直到服务器关闭,否则
application
对象中保存的信息会在整个应⽤中(程序运行期间)都有效。与session
对象相⽐,
application
对象⽣命周期更⻓,类似于系统的
“
全局变量
” ServletContext
作用域阶段(数据有效时间):
request:
单次请求期间的request中数据有效
session:
浏览器访问期间
(
会话期间
),session中存储的数据有效
application:
服务器启动期间
,
所存的数据可以跨浏览器
5、page 对象
page
对象代表
JSP
本身,只有在
JSP
⻚⾯内才是合法的。
page
隐含对象本质上包含当前
Servlet接⼝引⽤的变量,类似于Java
编程中的
this
指针。
java中使用this表示当前对象,jsp中使用page表示当前页面。
6、pageContext 对象
pageContext
对象的作⽤是
取得任何范围的参数
,通过它可以
获取 JSP⻚⾯的out、request、reponse、session、application 等对象
。
pageContext
对象的创建和初始化都是由容器来完成的,在JSP
⻚⾯中可以直接使⽤
pageContext
对象。
存取值得作用域是当前页面
7、out 对象
out
对象
⽤于向Web浏览器内输出信息
,并且管理应⽤服务器上的输出缓冲区。在使⽤
out
对 象输出数据时,可以对数据缓冲区进⾏操作,及时清除缓冲区中的残余数据,为其他的输出让出缓冲空间。待数据输出完毕后,要及时关闭输出流。
8、config 对象
config
对象的主要作⽤是
取得服务器的配置信息
。通过
pageConext对象的 getServletConfig()
⽅法可以获取⼀个config
对象。当⼀个
Servlet 初始化时,容器把某些信息通过config对象传递给这个Servlet
。 开发者可以在
web.xml
⽂件中为应⽤程序环境中的
Servlet
程序和
JSP
⻚⾯提供初始化参数
//将image路径转换成服务器端的路径
String url= config.getServletContext().getRealPath("/image");
<h1>url=<%=url %></h1>
9、exception 对象
exception
对象的作⽤是
显示异常信息
,只有
在包含 isErrorPage="true" 的⻚⾯中才可以被使⽤
, 在⼀般的JSP
⻚⾯中使⽤该对象将⽆法编译
JSP
⽂件。
excepation
对象和
Java
的所有对象⼀样,都具有系 统提供的继承结构。exception
对象⼏乎定义了所有异常情况。在
Java
程序中,可以使⽤
try/catch
关键 字来处理异常情况; 如果
在JSP⻚⾯中出现没有捕获到的异常,就会⽣成 exception 对象,并把 exception 对象传送到在page指令中设定的错误⻚⾯
中,然后在错误⻚⾯中处理相应的
exception
对象。
(1)
先在可能发⽣错误的⻚⾯中添加
errorPage
属性
:
<%@ page pageEncoding="utf-8" errorPage="error.jsp"
contentType="text/html;charset=UTF-8" language="java" %>
(2)
在
error.jsp
⻚⾯中设置
isErrorPage="true"
的属性
(
使⽤
exception
对象之前,需要先将当前⻚⾯设置成错误⻚⾯)
<%@ page language="java" isErrorPage="true" import="java.util.*"
pageEncoding="UTF-8"%>
jsp的作⽤域:
pageContext -> request -> session -> application
当前⻚⾯------
单次请求有效 ----
当前会话期间(多次请求) ---
服务器运⾏期间有效(多次会话,换浏览器访问,只要服务器不关闭,数据就在)
九大对象中只有这4个既可以做内置对象,也可以存储数据
下面演示单次请求、多次请求、多次会话期间数据的有效情况
九大内置对象.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<!--数据在一次请求响应期间有效-->
<%request.setAttribute("a","123");%>
request=<%=request.getAttribute("a")%>
<!--response作用域只在jsp页面有效-->
<% //response重定向 response.sendRedirect("...");%>
<%response.getWriter();%>
<%
//存储数据在当前会话期间有效
session.setAttribute("b","123");
%>
session:<%=session.getAttribute("b")%>
<%
//application存储数据在整个程序运行阶段有效
application.setAttribute("c","123");
%>
application=<%=application.getAttribute("c")%>
<%//page表示当前页面,相当于java中的this%>
<% //pageContext相当于对page的包装,工具类,可以存储数据,作用域是当前页面
pageContext.setAttribute("d",123);
%>
pageContext=<%=pageContext.getAttribute("d")%>
</body>
</html>
内置对象作用域.js
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<!--数据在一次请求响应期间有效-->
request=<%=request.getAttribute("a")%>
<!--存储数据在当前会话期间有效-->
session:<%=session.getAttribute("b")%>
<!--application存储数据在整个程序运行阶段有效-->
application=<%=application.getAttribute("c")%>
<!--pageContext相当于对page的包装,工具类,可以存储数据,作用域是当前页面-->
pageContext=<%=pageContext.getAttribute("d")%>
</body>
</html>
输入localhost:8080/九大内置对象.jsp,服务器返回响应结果,一次请求结束,request中数据失效
点击超链接,跳转到localhost:8080/内置对象作用域.jsp,属于第二次请求,request中数据失效
![](https://i-blog.csdnimg.cn/blog_migrate/8cb55c52a995515a4ccdc9ed25f3b48d.png)
重新打开或换浏览器访问localhost:8080/内置对象作用域.jsp,上次会话结束session数据失效
![](https://i-blog.csdnimg.cn/blog_migrate/8af719f2c9d0ad5575b6a750b7ae96b4.png)
当重启服务器后再访问,application数据也失效。
out和config对象的使用
<!--out对象,向浏览器输出数据和js脚本-->
<%out.print("<br>你好啊");
out.print("<h1>我很好<h1>");
%>
<%config.getInitParameter("")%>
Exception对象的使用
当页面出错时,跳转到自己定义的错误页面,而不是出现505等提示页面。
在可能出错的jsp页面的page指令中添加errorPage="error.jsp",当出现错误跳转到error.jsp
在error.jsp中的page指令添加isErrorPage="true"
exceptionpage.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="error.jsp" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>计算6/0的结果:<%=6/0%></h1>
</body>
</html>
error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>出错啦</h1>
exception:<%=exception.getMessage()%>
</body>
</html>
访问exceptionpage.jsp时直接跳转到错误页面
6. JSP的指令
JSP
指令⽤来
设置整个JSP⻚⾯相关的属性
,如⽹⻚的编码⽅式和脚本语⾔。
语法格式如下:
<%@ directive attribute="value" %>
directive:指令名称 attribute 属性名 value:属性值
(1)Page指令
Page
指令为容器提供当前⻚⾯的使⽤说明
⼀个
JSP
⻚⾯可以包含多个
page
指令
Page
指令的语法格式:
<%@ page attribute="value" %>
page指令的属性
(2) Include指令
JSP可以通过
include
指令来包含其他⽂件。
被包含的⽂件可以是
JSP
⽂件、
HTML
⽂件或⽂本⽂件
。
包含 的⽂件就好像是该JSP⽂件的⼀部分,会被同时编译执⾏
。
Include
指令的语法格式如下:
<%@ include file="⽂件相对 url 地址" %>
include 指令中的⽂件名实际上是⼀个相对的 URL 地址。
(3)Taglib指令
JSP API
允许⽤户⾃定义标签,⼀个⾃定义标签库就是⾃定义标签的集合。
Taglib
指令引⼊⼀个⾃定义标签集合的定义,包括库路径、⾃定义标签。
<%@ taglib uri="uri" prefix="" %>
uri
属性确定标签库的位置,
prefix
属性指定标签库的前缀
(
可⾃定义
)
。
引入自定义jsp文件演示实现一个页面中呈现是三个页面内容(类似html中的iframe框架/frameset)
top.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>头部.jsp</h1>
</body>
</html>
middle.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>中间.jsp</h1>
</body>
</html>
bottom.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>底部.jsp</h1>
</body>
</html>
7. 状态码
8. EL表达式(Expression Language )
之前使用小脚本方式在jsp页面进行动态数据的展示,嵌入java代码,实际开发中不使用小脚本去展示或嵌入,它既负责展示动态数据又要负责编写逻辑代码,可以通过EL表达式在jsp页面展示动态数据,实现动态数据的展示与业务逻辑分离。
EL表达式语法
${
需要展示信息的名字
}
注意:
如果要使用EL表达式读取变量,前提是要将变量存储在pageContext、request、session、application他们的作用域中
在不同作用域下这几个内置对象存在相同的key,el表达式会选择展示哪个值?
当表达式没有指定变量或者对象的范围时,那么容器会依次从
pageContext—>request—>session—>application中查找该变量或对象
,
我们可以通过隐含对象获得指定作⽤域的值:
pageScope
对象,⽤于获取当前⻚⾯的属性值
requestScope
对象,⽤于获取请求范围的属性值
sessionScope
对象,⽤于获取会话范围的属性值
applicationScope
对象,⽤于获取程序范围的属性值
语法
:
${requestScope.key}
EL中基础操作符
![](https://i-blog.csdnimg.cn/blog_migrate/7421711627eabcd63fef023f0f27ad66.png)
下面演示EL在jsp页面获取单个变量、单个对象、list、map数据
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Map" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
//EL表达式读取数据,前提是数据在pageConetxt/request/response/application作用域中
//下面直接在小脚本中存储数据,不在创建servlet中存
int a=10;
pageContext.setAttribute("A",a);//将变量存储内置对象pageContext中
List list = new ArrayList<>();
list.add("你好");
list.add("我很好");
pageContext.setAttribute("List",list);//将list存入pageContext作用域中
Map map=new HashMap();
map.put("name","chen");
map.put("pass","123");
pageContext.setAttribute("Map",map);//将map存入....作用域中
//不同作用域中存储相同的key的数据,el如何选择
pageContext.setAttribute("B","pageContext内容");
request.setAttribute("B","request内容");
session.setAttribute("B","session内容");
application.setAttribute("B","application内容");
//set是无序的,无法通过下表获取数据,需要标签库JSTL中的标签循环
%>
<!--下面使用EL读取数据-->
${100+200}<br>
${100>200}<br>
${100>200?"对":"不对"}<br>
<!--当表达式没有指定变量或者对象的范围时,那么容器会依次从
pageContext—>request—>session—>application中查找该变量或对象,
我们可以通过隐含对象获得指定作⽤域的值:
-->
a的值是:${A}<br>
a的值是:${pageContext.getAttribute("A")}<br>
a的值是:${pageScope.A}<br>
list所有数据:${List}<br>
list中第一数据:${List[0]}<br>
list中第二个数据:${pageContext.getAttribute("List")[1]}<br>
list中第二个数据:${pageScope.List[1]}<br>
map中所有数据:${Map}<br>
map中的数据name:${Map.name}<br>
map中的数据pass:${Map.pass}<br>
map中的数据pass:${pageScope.Map.pass}<br>
<!--我们可以通过隐含对象获得指定作⽤域的值:-->
pageContext-B:${pageScope.B}<br>
request-B:${requestScope.get("B")}<br>
session-B:${sessionScope.get("B")}<br>
application-B:${applicationScope.get("B")}<br>
</body>
</html>
9. JSTL
什么是JSTL
JSP标准标签库(JSTL)是⼀个JSP标签集合
,它封装了
JSP
应⽤的通⽤核⼼功能。
JSTL
⽀持通⽤的、结构化的任务,⽐如
迭代,条件判断,XML⽂档操作,国际化标签,SQL标签
。 除了这些,它还提供了⼀个框架来使⽤集成JSTL
的⾃定义标签。
根据
JSTL
标签所提供的功能,可以将其分为
5个类别。核⼼标签 格式化标签 sql标签 xml标签 jstl函数
![](https://i-blog.csdnimg.cn/blog_migrate/468e3b81a7ffb84aa6145183499919e3.png)
JSTL的作⽤和语法格式
作⽤:简化
jsp
⻚⾯编写代码
语法格式:
1.
下载
jakarta-taglibs-standard-1.1.2.zip
包并解压,将
jakarta-taglibs-standard-1.1.2/lib/
下的两个 jar
⽂件:
standard.jar
和
jstl.jar
⽂件拷⻉到
/WEB-INF/lib/
下。
2.
在
JSP
⻚⾯中引⼊
<%@ taglib prefix=”
⻚⾯使⽤的名称
” uri=”
功能范围的路径
”%>
核⼼标签
①核⼼标签是最常⽤的
JSTL
标签。引⽤核⼼标签库的语法如下:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
② 核⼼标签的分类
表达式操作
out
、
set
、
remove
、
catch
流程控制
if
、
choose
、
when
、
otherwise
迭代操作
forEach
、
forTokens
URL
操作
import
、
param
、
url
、
redirect
Set
标签
<
c:set>
主要⽤来将变量存储⾄
JSP
范围中或是
JavaBean
的属性或
Map
对象中
![](https://i-blog.csdnimg.cn/blog_migrate/dd6bc301758d58f6c721e0fb19e22c9b.png)
<
c:out>
主要⽤来显示数据的内容
![](https://i-blog.csdnimg.cn/blog_migrate/f500d7db7d2011502779f8950c2b5808.png)
<
c:remove>
主要负责移除变量
![](https://i-blog.csdnimg.cn/blog_migrate/2468f115c2dbd16efaecd0b09120886f.png)
<
c:if>
主要⽤于进⾏
if
判断
,
如果为
true,
则输出标签体中的内容
![](https://i-blog.csdnimg.cn/blog_migrate/41a826044f9f5285442c03e6c9da4702.png)
<
c:choose>,
<
c:when>,
<
c:otherwise>
作⽤相当于
if-else
![](https://i-blog.csdnimg.cn/blog_migrate/17f8860cf477f042ad4e97ed7f9f9708.png)
<
c:forEach>
循环控制,它可以将数组
,
集合
(Collection)
中的成员循序浏览⼀遍。
![](https://i-blog.csdnimg.cn/blog_migrate/c64072c7b61aa2d17fb4300f32423b47.png)
格式化标签
1
、
fmt:formatDate
作⽤:将⽇期类型格式化为指定模式的字符串
属性
value:
将要被格式化的数据
pattern
:格式化的模式,与
SimpleDateFormat
的参数设置⼀样
var:
格式化后的字符串所要存放的变量,若不指定
var
,则会将格式化的结果直接显示在⻚⾯
scope
:变量存放的域属性空间,默认
page
type
:其取值为
date
、
time
、
both
,表示给出的
value
是⽇期、时间、还是两者都包含,默认是
date
2
、
fmt:parseDate
作⽤:⽤于将指定字符串转化为⽇期类型
<fmt:parseDate value="${now }" pattern="yyyy-MM-dd" var="today"/>
Value
服务器获取的时间
Pattern:
转换的格式
Var:
⻚⾯显示的变量
3
、
fmt:formatNumber
按照指定格式对数字进⾏格式化
属性
maxIntegerDigits
:整数部分最多的位数
minIntegerDigits
:整数部分最少的位数
maxFrctionDigits
:⼩数部分最多的位数
minFrctionDigits
:⼩数部分最少的位数
var
:存储格式化结果的变量
scope
:
var
属性的作⽤域
integerOnly
:是否只解析整型数
true
或者浮点数
false
主要演示核心标签库c标签中的If、choose、forEach以及格式化标签fmt的时间格式化
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.text.DateFormat" %>
<%@ page import="java.util.Date" %><%--
Created by IntelliJ IDEA.
User: 陈伯维
Date: 2021/3/10
Time: 17:00
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!--引入核心标签库-->
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!--引入格式化标签库-->
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>$JSTL核心标签</title>
</head>
<body>
<!--存值,键值对存储以及存在哪个域对象中-->
<c:set var="uname" value="小陈" scope="session"></c:set>
<!--在页面显示数据,获取session中的uname的值-->
<c:out value="${sessionScope.uname}"></c:out><br>
<!--if判断语句 test为true则展示-->
<c:if test="${sessionScope.uname=='小陈'}">if判断session的uname是小陈</c:if><br>
<!--if else语句 when是if otherwise是else-->
<c:choose>
<c:when test="${sessionScope.uname='小乔'}">这是小乔啊</c:when>
<c:otherwise>这是小陈啊</c:otherwise>
</c:choose><br>
<!--forEach循环,先在小脚本中给域对象存入一个list集合-->
<%
List list=new ArrayList();
list.add("1");
list.add("2");
list.add("3");
pageContext.setAttribute("List",list);//将list数据存入域对象
%>
<!--遍历list items获取集合 var当前遍历的元素
varStatus当前元素相关信息,它的count属性和index属性都是计数的,前者从1,后者从0计数-->
<c:forEach items="${pageScope.List}" var="num" varStatus="sta">
${sta.count}--${sta.index}--${num}<br>
</c:forEach>
<!--在小脚本中向域对象存入一个时间-->
<% pageContext.setAttribute("nowTime",new Date());%>
<!--通过格式化标签来格式化时间-->
date:${nowTime}<br> <!--通过el的$直接获取的值是美国时间格式-->
date:<fmt:formatDate value="${nowTime}" pattern="yyyy-MM-dd"></fmt:formatDate>
</body>
</html>