会话管理

HTTP是无状态协议 所以对话只在POST和GET中实现
换句话说就是 在浏览器里走个过场 啥也没留下

会话的数据会保存在浏览器客户端 例如:显示 XXX用户上次登录的时间

核心api

image-20231204101100496

Cookie原理

1)服务器创建cookie对象,把会话数据存储到cookie对象中。

1
Cookie cookie = new Cookie("username","lsieun");

2) 服务器发送cookie信息到浏览器

1
response.addCookie(cookie);

举例: Set-Cookie: username=lsieun (隐藏发送了一个Set-Cookie名称的响应头)

image-20231204101312698

3)浏览器得到服务器发送的cookie,然后保存在浏览器端。

4)浏览器在下次访问服务器时,会带着cookie信息

举例: Cookie: username=lsieun (隐藏带着一个叫Cookie名称的请求头)

image-20231204101331228

5)服务器接收到浏览器带来的cookie信息

1
2
3
4
5
6
7
8
9
10
11
12
Cookie[] cookies = request.getCookies();//接收浏览器发送的cookie信息
if(cookies != null)
{
for(Cookie c : cookies)
{
String cookieName = c.getName();
String cookieValue = c.getValue();
int cookieAge = c.getMaxAge();

out.write(cookieName + ": " + cookieValue + ", Age: " + cookieAge);
}
}

Seesion

Cookie 可以让服务端程序跟踪每个客户端的访问,但是每次客户端的访问都必须传回这些 Cookie,如果 Cookie 很多,则无形增加了客户端与服务端的数据传输量,而Session 的出现正是为了解决这个问题。

同一个客户端每次和服务端交互时,不需要每次都传回所有的 Cookie 值,而是只要传回一个 ID,这个 ID 就是客户端第一次访问服务器生成的,而且每个客户端是唯一的。这样每个客户端就有了一个唯一的 ID,客户端只要传回这个 ID 就行了,这个 ID 通常是 NAME 为 JSESIONID 的一个 Cookie。

  1. 获取 Session 对象 request对象.getSession() 和参数为true的一样 request对象.getSession(true) 获取Session对象,如果没有Session对象,直接创建一个新的返回,缺省值 request对象.getSession(false) 获取Session对象,如果没有返回null

  2. 设置共享数据

    1
    Session对象.setAttribute(String name, Object value)
  • 注意:Session 可以**存储任何类型的数据,**比如登陆用户的信息,可以封装到User对象中

3.修改共享数据 重新设置一个同名的共享数据

4.获取共享数据

1
Object value = Session对象.getAttribute(String name);

5.删除 Session 中的共享数据

1
Session对象.removeAttribute(String name);

6.销毁 Session

1
void invalidate() 

7.Session 的超时管理

  • 超时:在访问当前的资源的过程中,不和网页进行任何的交互,超过设定的时间就是超时 在 Tomcat 服务器中有默认的配置为30分钟,一般不需要去修改
  • 语法:void setMaxInactiveInterval(int interval)

Filter过滤器

image-20231205162123708

图解:

image-20231205164157296

一般开发的场景应用:

  • 日志的记录
  • 性能的分析
  • 乱码的处理
  • 事务控制
  • 登录控制
  • 跨域的处理

Demo:

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.wilsit.schedule.test.Filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServlet;
import java.io.IOException;


/**
* 1 实现Filter接口
* 2.重写过滤方法
* 3.配置过滤器
* web.xml
* 注解
* @DATA 2023/12/5
* @author <a href="mailto:WISLIST"
*/
@WebFilter("/*")
// "/*" 过滤全部资源 /a/* *.html
public class LogingFilter implements Filter {
/*
* 过滤请求的方法
* 1 请求到达目标资源之前,先经过该方法
* 2 该方法有能力控制请求是否继续进行
* 3 响应的时候还会经过该方法 但是无法控制是否响应
*
* */

@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain/*过滤链 允许多个过滤器*/ filterChain) throws IOException, ServletException {
/*
* 1 判断是否登录 校验权限是否满足
* 2 放行代码
*
* 3 响应之前 HttpServletResponse 转化为响应报文之前的功能代码
* */
// 功能代码
System.out.println("logingFilter before doFilter invoked");

filterChain.doFilter(servletRequest, servletResponse);
//响应之前的功能代码
System.out.println("logingFilter before doFilter invoked");
}

@Override
public void destroy() {

}


}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.wilsit.schedule.test.Filter;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import java.io.IOException;

@WebServlet("/servlet1")
public class LogingServlet extends HttpServlet{

@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("service ");
res.getWriter().write("servlet1 meassage");
}


}

Filter链

image-20231205213411182

执行流程:

image-20231205214510327

filter执行顺序:

image-20231205214647540

是通过xml中的filter-mapping的先后来判断的

如果用注解呢?
image-20231205220523876

可以通过F1-Filter 来当1
F2-Filter来当2

Listener 监听器

image-20231205220714331

分类:

image-20231206084727605

钝化活化监听器:

其实就是将Session存到磁盘中 降低内存的消耗 在通过session监听器来调节

image-20231206190606581

image-20231206190615144