Ajax&json

Ajax

Ajax介绍

Asynchronous JavaScript And XML(异步的 JavaScript 和 XML)

Ajax可以在不刷新页面的前提下,进行页面局部更新

Ajax是前端开发的必备技能,也是主流的开发模式

Ajax使用流程

创建XmlHttpRequest对象

发送Ajax请求

处理服务器响应

1672712431738

1672712472194

1672712503858

因为默认端口号是80,所以可以不写。

1-创建XMLHttpRequest对象

XMLHttpRequest是Ajax的核心,Ajax使用该对象发起请求、接收响应

XMLHttpRequest并不是W3C的标准,不同浏览器的创建方式不同

1
2
3
4
5
6
7
8
9
10
11
var xmlhttp;
if (window.XMLHttpRequest)
{
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xmlhttp = new XMLHttpRequest();
}
else
{
// IE6, IE5 浏览器执行代码
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

1672713138837

1672713168745

2-发送Ajax请求

xmlhttp.open()用于创建请求

xmlhttp.send()用于发送请求

1
2
3
4
//创建请求
xmlhttp.open("GET","http://loaclhost/test?name=admin");
//发送到服务器
xmlhttp.send();

1672713521475

1672713533365

1672714274344

1672714253200

3-处理服务器响应

  • Xmlhttp.onreadystatechange() 事件用于监听Ajax的执行过程

  • xmlhttp.readyState属性说明XMLHttpRequest当前状态

readyState值 说明
readyState = 0 请求未初始化
readyState = 1 服务器连接已建立
readyState = 2 请求已被接收
readyState = 3 请求正在处理
readyState = 4 响应文本已被接收
  • xmlhttp.status属性服务器响应状态码, 200:成功 404:未找到…

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    xmlhttp.onreadystatechange = function()
    {
    //响应已被接收且服务器处理成功时才执行
    if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    //获取响应体的文本
    var responseText = xmlhttp.responseText;
    //对服务器结果进行处理
    ...
    }
    }

1672715588203

1672715612766

1672715630238

1672715739787

1672715748778


JSON

JSON介绍

JavaScript Object Notation(JavaScript对象表示法)

JSON 是轻量级的文本数据交换格式

JSNO 独立于语言,具有自我描述性,更易理解

1
2
3
4
5
6
7
{
"site":[
{"name":"Github","url":"www.github.com"},
{"name":"百度","url":"www.baidu.com"},
{"name":"网易","url":"www.163.com"}
]
}

JSON语法规则

数据由键(key)/值(value)描述,由冒号分隔

大括号代表一个完整的对象,拥有多个键/值对

中括号保存数组,多个对象之间使用逗号分隔

利用JSON保存员工数据

1672751871201

1672751884334

1672752050126

JavaScript操作JSON

1672752553297

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
var employeeList = [
{
"empno": 7369,
"ename": "李宁",
"job": "软件工程师",
"hiredate": "2019-5-12",
"salary": 13000,
"dname": "研发部"
},
{
"empno": 7499,
"ename": "王乐",
"job": "客户经理",
"hiredate": "2017-4-22",
"salary": 10000,
"dname": "市场部",
"customers": [
{
"cname": "李东"
},
{
"cname": "刘楠"
}
]
}
];
for (var i = 0;i < employeeList.length; i++) {
var employee = employeeList[i];
console.log(employee);
}
</script>
</head>
<body>

</body>
</html>

1672752458073

1672753000385

1672753029201

1672753343182

1672753388364


Ajax应用实践

Ajax+JSON开发模式

1672753985228

Jackson

Jackson是国内外著名的Java开源JSON序列化组件

Jackson国内拥有大量使用者,拥有API简单,效率等优点

Jackson也是众多Java框架的底层组件,掌握Jackson很重要

1672754836507

1672755275134

利用Jackson实现JSON序列化输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@WebServlet("/news")
public class NewsServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List<News> list = new ArrayList<>();
list.add(new News("TIOBE:2020年编程语言排行趋势","2020-5-1","TIOBE","..."));
list.add(new News("TIOBE:2021年编程语言排行趋势","2021-5-1","TIOBE","..."));
list.add(new News("TIOBE:2022年编程语言排行趋势","2022-5-1","TIOBE","..."));
list.add(new News("TIOBE:2023年编程语言排行趋势","2023-5-1","TIOBE","..."));
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(list);
resp.setContentType("text/json;charset=utf-8");
resp.getWriter().println(json);
}
}

1672756962899

记得往lib中加入下好的依赖

1672760319589


Ajax处理JSON数据

1672760833244

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="container"></div>
<script>
var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
}else{
xmlhttp = new ActiveXObject("microsoft.XMLHTTP");
}
xmlhttp.open("GET", "/news");
xmlhttp.send();
xmlhttp.onreadystatechange = function (){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
var str = xmlhttp.responseText;
console.log(str);
}
}
</script>
</body>
</html>

1672760990398

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="container"></div>
<script>
var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
}else{
xmlhttp = new ActiveXObject("microsoft.XMLHTTP");
}
xmlhttp.open("GET", "/news");
xmlhttp.send();
xmlhttp.onreadystatechange = function (){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
var str = xmlhttp.responseText;
console.log(str);
var json = JSON.parse(str);
console.log(json);
}
}
</script>
</body>
</html>

1672761190963

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="container"></div>
<script>
var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
}else{
xmlhttp = new ActiveXObject("microsoft.XMLHTTP");
}
xmlhttp.open("GET", "/news");
xmlhttp.send();
xmlhttp.onreadystatechange = function (){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
var str = xmlhttp.responseText;
console.log(str);
var json = JSON.parse(str);
console.log(json);
for (var i = 0;i < json.length ; i++) {
var news = json[i];
var container = document.getElementById("container");
container.innerHTML = container.innerHTML + news.title;
}
}
}
</script>
</body>
</html>

1672761434657

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
}else{
xmlhttp = new ActiveXObject("microsoft.XMLHTTP");
}
xmlhttp.open("GET", "/news");
xmlhttp.send();
xmlhttp.onreadystatechange = function (){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
var str = xmlhttp.responseText;
console.log(str);
var json = JSON.parse(str);
console.log(json);
for (var i = 0;i < json.length ; i++) {
var news = json[i];
var container = document.getElementById("container");
container.innerHTML = container.innerHTML + "<h2>" + news.title + "</h2>";
}
}
}
</script>

1672761525759


Axios快速入门

https://www.axios-http.cn/

1672761880070

使用 unpkg CDN:

1
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

1672762171879

Axios发送Get请求

1672762337362

1672762672565

1672762767042

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/js/axios.js"></script>
</head>
<body>
<div id="container"></div>
<script>
axios.get('/news',{}).then(function (response){
console.log(response);
var json = response.data;
for (var i = 0;i < json.length ; i++) {
var news = json[i];
var container = document.getElementById("container");
container.innerHTML = container.innerHTML + "<h2>" + news.title + "</h2>";
}
}).catch(function (error){
console.log(error);
})
</script>
</body>
</html>

1672762899918

1672763169965

1672763469144

或者写成

1
axios.get('/news?t=pypl').then(function (response)

1672763506181

1672763534273


Axios发送Post请求

在axios.html中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/js/axios.js"></script>
</head>
<body>
<div id="container"></div>
<script>
axios.post('/news', "t=pypl&l=abc", {headers:{"content-type":"application/x-www-form-urlencoded"}})
.then(function (response){
console.log(response);
var json = response.data;
for (var i = 0;i < json.length ; i++) {
var news = json[i];
var container = document.getElementById("container");
container.innerHTML = container.innerHTML + "<h2>" + news.title + "</h2>";
}
})
.catch(function (error){
console.log(error);
});
</script>
</body>
</html>

1672800673862

发现405错误,原因是没写doPost方法。

16728007275281672800753131

说明传递成功。

1672800838446

解决405,在里面追加doPost方法。

1672800966289

扩展:

请求参数过多的话开源采用面向对象方法

1672801272252

1672801322926


Ajax同步与异步的区别

同步是在服务器未返回JSON前,JS程序一直处于阻塞等待的状态

异步是在服务器未返回JSON前,不阻塞程序,Ajax通过回调获取结果

1672801687323

创建和news基础上改动的async.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="container"></div>
<script>
var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
}else{
xmlhttp = new ActiveXObject("microsoft.XMLHTTP");
}
xmlhttp.open("GET", "/news?t=pypl");
xmlhttp.send();
console.log("请求数据已发送");
xmlhttp.onreadystatechange = function (){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
var str = xmlhttp.responseText;
console.log(str);
var json = JSON.parse(str);
console.log(json);
for (var i = 0;i < json.length ; i++) {
var news = json[i];
var container = document.getElementById("container");
container.innerHTML = container.innerHTML + "<h2>" + news.title + "</h2>";
}
}
}
</script>
</body>
</html>

newsServlet类中,睡眠5s后进行以下代码

1672802011659

1672802052911

1672802146140

第三个参数设为false表示关闭异步,开启同步。

1672802227909

只能显示出日志

1672802402707

将onchange下面的内容提到日志下面就可以同步进行

1672802460936

开发时基本上用的是异步。


实现二级联动菜单

1672803956074

1672803969982

1672803982793

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@WebServlet("/channel")
public class ChannelServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String level = req.getParameter("level");
String parent = req.getParameter("parent");
List<Channel> chlist = new ArrayList<>();
if (level.equals("1")){
chlist.add(new Channel("ai","人工智能"));
chlist.add(new Channel("web","前端开发"));
} else if (level.equals("2")) {
if (parent.equals("ai")){
chlist.add(new Channel("dl","深度学习"));
chlist.add(new Channel("cv","计算机视觉"));
chlist.add(new Channel("nlp","自然语言处理"));
} else if (parent.equals("web")) {
chlist.add(new Channel("html","HTML超文本标记语言"));
chlist.add(new Channel("css","CSS极联样式表"));
chlist.add(new Channel("js","JavaScript脚本"));
}
}
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(chlist);
resp.setContentType("application/json;charset=utf-8");
resp.getWriter().println(json);
}
}

1672804044727

1672804083078

1672804258532

1672804297071

1672833678061

1672833683961

1672833701775

1672833855925

1672833841751

1672834209435

onchange为复选框选择事件

1672834198382

再把数据填充到二级下拉框中。

1672834573306

1672834780200

1672834808518

但选择前端开发时出现bug

1672834839316

再选择回来,发生叠加。

1672834872709

所以每次加载都要清除原来的数据

1672834982693


Java正则表达式

正则表达式基础语法

正则表达式介绍

什么是正则表达式

正则表达式是检查、匹配字符串的表达式

正则表达式是描述规则,主流语言都有良好支持

字符串校验、查找与替换是正则表达式主要使用场景

正则表达式案例

检查输入的身份证号是否合法(15位、18位)

示例:13010220200328091X

正则表达式:

1
(^\d{15}$)|(^\d{18}&)|(^\d{17}(\d|X|x)$)

字符范围匹配

1672836411879

在线表达式测试工具https://tool.oschina.net/regex

eg:精准匹配hello或hallo

1
h[ea]llo

匹配数字范围(0570-0579)

1
057[0-9]

单选题只允许输入ABCD其中一项

1
[ABCD]或者[A-D]

元字符

1672837103320

eg:

请匹配数字(3213.383219)

1
\d\d\d\d\.\d\d\d\d\d\d

匹配杭州与宁波座机号码(0571|0574-XXXXXXXX)

1
057[14]-\d\d\d\d\d\d\d\d

请匹配18位身份证号

1
[1234568]\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d[0-9xX]
1
[1234568]\d{16}[0-9xX]

多次重复匹配

1672839364308

eg:

验证短信验证码 (321456)

1
\d{6}

请匹配全国座机号(区号3或者4位-电话号码7或8位)

1
\d{3,4}-\d{7,8}

请匹配英文姓名(例如:James Watson)

1
[A-Z][a-z]{1,}\s[A-Z][a-z]{0,}
1
[A-Z][a-z]+\s[A-Z][a-z]*

定位匹配

1672839885513

.*是指任意长度的字符

eg:匹配ab开头ab结尾的字符串

1
^ab.*ab$

贪婪模式

在满足条件的情况下尽可能多匹配到字符串

示例:111222333 正则:\d{6,8}

匹配结果:11122233

非贪婪模式

在满足条件的情况下尽可能少匹配字符串

示例:111222333 正则:\d{6,8}?

匹配结果:111222

eg:提取超链接里的网址

1
<a href="www.baidu.com">百度</a><a href="www.sina.com">新浪</a>

贪婪正则:

1
".*"

1672840488037

非贪婪正则:

1
".*?"

1672840531552

表达式分组

分组将”正则”分组为多个子表达式

示例:abababcdcdcd

正则表达式:(ab){3}(cd){3}

eg:

匹配验证码(4位或6位)

1
(^\d{4}$)|(^\d{6}$)

匹配车牌号(粤D-U888G)

1
^([冀黑粤晋][A-Z])-([A-Z0-9]{5})$

匹配中文或英文姓名

James Watson

1
^[A-Z][a-Z]+\s[A-Z][a-z]*$

张三

1
^[\u4e00-\u9fa5]{2,8}$

再混合

1
(^[A-Z][a-Z]+\s[A-Z][a-z]*$)|(^[\u4e00-\u9fa5]{2,8}$)

应用实例

JavaScript表单验证

1672886314775

1672886381094

1672886959003

1672887010045


过滤器

Filter过滤器基础

初识过滤器-Filter

1672888159673

过滤器-Filter

过滤器(Filter)是J2EE Servlet模块下的组件

Filter的作用是对URI进行统一的拦截处理

Filter通常用于应用程序层面进行请求的前置处理

过滤链

1672888450032

开发第一个过滤器

开发过滤器三要素

任何过滤器都要实现javax.servlet.Filter接口

在Filter接口的doFilter()方法中编写过滤器的功能代码

在web.xml中对过滤器进行配置,定义拦截URI的范围

1672889013734

1672889000709

1672889041751

1672889047875

1672889234395

1672889366284

1672889515502

1672889872405

1672889881980

1672891062598

1672891068269

如果将filterChain.doFilter()注释掉,可以看到,控制台有输出,但页面没有输出

1672891195929

1672891178266

1672891182927

访问/hello也是同样效果


过滤器生命周期

1672919973932

1672920077935

开启tomcat时就进行。

1672920232709

重启Tomcat时销毁。

过滤器的特性

过滤器对象在Web应用启动时被创建且全局唯一

唯一的过滤器针对性在并发环境中采用”多线程”提供服务


过滤器应用实践

WebFilter注解的使用

过滤器配置形式

1
2
3
4
5
6
7
8
<filter>
<filter-name>firstFilter</filter-name>
<filter-class>org.example.filter.FistFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>firstFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

过滤器注解形式

1
2
3
4
@WebFilter(filterName="annotationFilter", urlPatterns="/*")
public class AnnotationFilter implements Filter {
...
}

1672921662667

1672923361858

配置与注解如何选择

配置形式维护性更好,适合应用全局过滤

注释形式开发体验更好,适用于小型项目敏捷开发


开发字符集过滤器

Web中文乱码的解决

GET请求-server.xml增加URIEncoding=”UTF-8”

POST请求-使用request.setCharacterEncoding(“UTF-8”)

响应-response.setContentType(“text/html;charset=utf-8”)

由于每次可能都要设置以上内容,所以有了字符集过滤器来便利。

ServletRequest接口

1672923995580

1672924125109

1672924177632

1672924391551

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class CharacterEncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
filterChain.doFilter(servletRequest, servletResponse);
}

@Override
public void destroy() {

}
}

1672924506212

1672924539746

1672924605471

这样,我们在开发时就不用再注意去加上编码。


参数化过滤器

过滤器参数化

过滤器为了增强灵活性,允许配置信息放在web.xml

在web.xml中配置设置过滤器参数

优化字符集过滤器

1672927730493

1672928403838

1672927965655

1672928010358

1672928023190

1672928111720

用注释形式的话(了解):

1672928510553


url-pattern常用写法

/index.html - 执行资源精准匹配

/servlet/* - 以前缀进行模糊匹配

*.html - 以后缀进行模糊匹配

但不支持前缀加后缀

1672928869054

1672928959915

16729290344091672929044609

后缀匹配:

1672929185218

前缀匹配:

1672929213681

1672929292397

1672929299564

/与/*的区别

/ 应用在Servlet配置,使该Servlet替代主页

/* 应用在过滤器,代表对所有请求拦截

1672929633066

1672929641578

1672929688237

原本的index.html失效了。

1672929745979


过滤链的开发技巧

过滤链

1672929854073

过滤链开发注意事项

每一个过滤器应具有单独职能

过滤器的执行顺序以为准

调用chain.doFilter()将请求向后传递

1672930240180

1672930213943

1672930230865

1672930288552

1672930339584

如果在Filter中忘了写

1
filterChain.doFilter(servletRequest, servletResponse);

的话:

1672930524299

1672930551984

1672930544618

杜绝了后面过滤器的执行。

1672930700130

注解形式是按filterName中字母顺序执行的,这样会降低对程序的维护性。


利用过滤器实现多端匹配

多端设备自动匹配

1672932400962

1672932648378

1672933553364

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class DeviceAdapterFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
String uri = req.getRequestURI();
/ //index.html -> /mobile/index.html / /desktop/index.html
String userAgent = req.getHeader("user-agent");
String targetUri = null;
if (userAgent.toLowerCase().indexOf("android") != -1 || userAgent.toLowerCase().indexOf("iphone") != -1){
targetUri = "/mobile" + uri; // /mobile/index.html
System.out.println("移动端正在访问,重新跳转URI:" + targetUri);
}else {
targetUri = "/desktop" + uri;
System.out.println("PC端正在访问,重新跳转URI:" + targetUri);
}
resp.sendRedirect(targetUri);
}

@Override
public void destroy() {

}
}

web.xml

1
2
3
4
5
6
7
8
9
<filter>
<filter-name>deviceAdaptFilter</filter-name>
<filter-class>org.example.filter.DeviceAdapterFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>deviceAdaptFilter</filter-name>
<url-pattern>*.html</url-pattern>
</filter-mapping>

此时运行,访问index.html

会出现错误,多次重定向。

1672934066310

要再加上一个前置判断

1672934358418

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class DeviceAdapterFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
String uri = req.getRequestURI(); ///index.html -> /mobile/index.html / /desktop/index.html
String userAgent = req.getHeader("user-agent");
String targetUri = null;
if (uri.startsWith("/desktop") || uri.startsWith("/mobile")) {
filterChain.doFilter(servletRequest, servletResponse);
} else {
if (userAgent.toLowerCase().indexOf("android") != -1 || userAgent.toLowerCase().indexOf("iphone") != -1) {
targetUri = "/mobile" + uri; // /mobile/index.html
System.out.println("移动端正在访问,重新跳转URI:" + targetUri);
} else {
targetUri = "/desktop" + uri;
System.out.println("PC端正在访问,重新跳转URI:" + targetUri);
}
resp.sendRedirect(targetUri);
}
}

@Override
public void destroy() {

}
}

此时输入http://localhost:8080/index.html

1672934651039

按F12进入手机模式,再输入http://localhost:8080/index.html

1672934743528

1672934855855


监听器(了解)

监听器-Listener

监听器(Listener)是J2EE Servlet模块下的组件

Listener的作用对Web应用对象的行为进行监控

通过Listener监听自动触发指定的功能代码

过滤器与监听器的区别

过滤器(Filter)的职责是对URL进行过滤拦截,是主动的执行

监听器(Listener)的职责是对Web对象进行监听,是被动触发

三种监听对象

ServletContext - 对全局ServletContext及其属性进行监听

HttpSession - 对用户会话及其属性操作进行监听

ServletRequest - 对请求及属性操作进行监听

1672936668427

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class WebListener implements ServletContextListener, HttpSessionListener, ServletRequestListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext object has been created");
}

@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext object has been destroyed");
}

@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("Request destroyed");
}

@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("Request created");
}

@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("Session created");
}

@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("Session destroyed");
}
}

web.xml

1
2
3
<listener>
<listener-class>org.example.WebListener</listener-class>
</listener>

1672937054498

重启时

1672937104902

1672937174422

1672937168419

而Session会话监听会在getSession()时触发,但销毁会在服务器关闭的30分钟后才进行。

监听器在现在已经用得很少了,了解一下即可。