目录

一:Session监听器

1:session种类简介

2:session生命周期 (HttpSessionListener)

2.1:创建:

2.2:销毁

2.3:session的创建和销毁以及活化、钝化的流程;

3:session域中属性的变化(HttpSessioniAttributeListener)

4:session钝化和活化监听器(HttpSessionActivationListener)

5:session的绑定对象和解绑监听器

二:cookie

1:Cookie(总结:浏览器端保存少量数据的一种技术;)

1.1:什么是 Cookie?

1.2:特点

1.3:cookie的有效时间

2:如何创建 Cookie

3:服务器如何获取 Cookie

4:Cookie 值的修改(同名cookie覆盖)

5:浏览器查看cookie

6:Cookie 生命控制 

三:Session会话

1:什么是 Session  会话?

2:如何创建 Session  和获取(id  号, 是否为新)

2.1request.getSession()

2.2:isNew(); 判断到底是不是刚创建出来的(新的)

2.3:getId() 得到 Session 的会话 id 值。

3:Session 域数据的存取

3.1:向Session中存数据

3.2:从Session中取数据

4:Session 生命周期控制

4.1Session 默认的超时时长是多少!Session 默认的超时时间长为 30 分钟。

4.2:修改默认Session超时时间

4.3:设置Session超时时间

5:  浏览器和 Session 之间关联的技术内幕

四:cookie、session会话机制

五:令牌机制

1:页面代码:

2:后台代码:

六:token机制认证方法


前言:

他们的执行顺序:spring的注入是在filter和listener之后的,(顺序是这样的listener >>  filter >> servlet >>  spring )

一:Session监听器

1:session种类简介

  • ServletContext

¨       生命周期监听:ServletContextListener,它有两个方法,一个在出生时调用,一个在死亡时调用;

²       void contextInitialized(ServletContextEvent sce):创建SErvletcontext时

²       void contextDestroyed(ServletContextEvent sce):销毁Servletcontext时

¨       属性监听:ServletContextAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。

²      void attributeAdded(ServletContextAttributeEvent event):添加属性时;

²      void attributeReplaced(ServletContextAttributeEvent event):替换属性时;

²     void attributeRemoved(ServletContextAttributeEvent event):移除属性时;

  • HttpSession

¨       生命周期监听:HttpSessionListener,它有两个方法,一个在出生时调用,一个在死亡时调用;

²      void sessionCreated(HttpSessionEvent se):创建session时

²      void sessionDestroyed(HttpSessionEvent se):销毁session时

¨       属性监听:HttpSessioniAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。

²      void attributeAdded(HttpSessionBindingEvent event):添加属性时;

²      void attributeReplaced(HttpSessionBindingEvent event):替换属性时

²      void attributeRemoved(HttpSessionBindingEvent event):移除属性时

  • ServletRequest

¨       生命周期监听:ServletRequestListener,它有两个方法,一个在出生时调用,一个在死亡时调用;

²       void requestInitialized(ServletRequestEvent sre):创建request时

²       void requestDestroyed(ServletRequestEvent sre):销毁request时

¨       属性监听:ServletRequestAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。

²       void attributeAdded(ServletRequestAttributeEvent srae):添加属性时

²       void attributeReplaced(ServletRequestAttributeEvent srae):替换属性时

²       void attributeRemoved(ServletRequestAttributeEvent srae):移除属性时

javaWeb中完成编写监听器:

  • 写一个监听器类:要求必须去实现某个监听器接口;
  • 注册,是在web.xml中配置来完成注册!

 注:还有两个是关于session的监听器,和上边的不一样;

HttpSessionBindingListener:当某个类实现了该接口后,可以感知本类对象添加到session中,以及感知从session中移除。例如让Person类实现HttpSessionBindingListener接口,那么当把Person对象添加到session中,或者把Person对象从session中移除时会调用下面两个方法:

  • public void valueBound(HttpSessionBindingEvent event):当把监听器对象添加到session中会调用监听器对象的本方法;
  • public void valueUnbound(HttpSessionBindingEvent event):当把监听器对象从session中移除时会调用监听器对象的本方法;
  • 这里要注意,HttpSessionBindingListener监听器的使用与前面介绍的都不相同,当该监听器对象添加到session中,或把该监听器对象从session移除时会调用监听器中的方法。并且无需在web.xml文件中部署这个监听器.

HttpSessionActivationListener:Tomcat会在session从时间不被使用时钝化session对象,所谓钝化session,就是把session通过序列化的方式保存到硬盘文件中。当用户再使用session时,Tomcat还会把钝化的对象再活化session,所谓活化就是把硬盘文件中的session在反序列化回内存。当session被Tomcat钝化时,session中存储的对象也被纯化,当session被活化时,也会把session中存储的对象活化。如果某个类实现了HttpSessionActiveationListener接口后,当对象随着session被钝化和活化时,下面两个方法就会被调用:

  • public void sessionWillPassivate(HttpSessionEvent se):当对象感知被活化时调用本方法;
  • public void sessionDidActivate(HttpSessionEvent se):当对象感知被钝化时调用本方法;

HttpSessionActivationListener监听器与HttpSessionBindingListener监听器相似,都是感知型的监听器,例如让Person类实现了HttpSessionActivationListener监听器接口,并把Person对象添加到了session中后,当Tomcat钝化session时,同时也会钝化session中的Person对象,这时Person对象就会感知到自己被钝化了,其实就是调用Person对象的sessionWillPassivate()方法。当用户再次使用session时,Tomcat会活化session,这时Person会感知到自己被活化,其实就是调用Person对象的sessionDidActivate()方法。

注意,因为钝化和活化session,其实就是使用序列化和反序列化技术把session从内存保存到硬盘,和把session从硬盘加载到内存。这说明如果Person类没有实现Serializable接口,那么当session钝化时就不会钝化Person,而是把Person从session中移除再钝化!这也说明session活化后,session中就不在有Person对象了。

2:session生命周期 (HttpSessionListener)

package com.wkl.lisener;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

/**
 * Description:
 * Date:       2020/8/28 - 上午 10:37
 * author:     wangkanglu
 * version:    V1.0
 */
public class SessionLisener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("session创建。。。"+se.getSession().getId());
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("session销毁。。。"+se.getSession().getId());
    }
}

注册:

Spring Authorization Server PKCE刷新token springsession token_监听器

2.1:创建:

              1):第一次访问jsp;因为session是内置的;没有就要创建

              2):以后任意一次访问都会携带cookie中的sessionid,服务器中有这个session就不用创建;否则应该创建

2.2:销毁

         session超时自动销毁

         session手动销毁

HttpSession session = request.getSession();
 session.invalidate();

2.3:session的创建和销毁以及活化、钝化的流程;

1:服务器第一次启动时;因为默认访问首页(index.jsp),所以自动创建session;

Spring Authorization Server PKCE刷新token springsession token_服务器_02

Spring Authorization Server PKCE刷新token springsession token_服务器_03

2:当服务器访问其他的jsp或者访问接口;返回系统现在的session时;都会放回第一次创建的session;因为访问时请求头会带着session的信息;

Spring Authorization Server PKCE刷新token springsession token_监听器_04

3:如果服务器关闭重新启动,之前的session钝化(存在硬盘中),服务启动有重新活化(从银盘中读取);这时候服务器访问首页又创建新的session;这时候浏览器cookie存的是过去的sessionid;浏览器带着过去的sessionid访问接口;这时候服务器会将新的session返回来;浏览器重新保存在cookie中;

Spring Authorization Server PKCE刷新token springsession token_监听器_05

4:如果浏览器关闭了;cookie清空了;那么下次访问时,浏览器带着空白的session访问服务器;这时候服务器会重新创建新的session;

 

Spring Authorization Server PKCE刷新token springsession token_服务器_06

3:session域中属性的变化(HttpSessioniAttributeListener)

package com.wkl.lisener;

import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

/**
 * Description:
 * Date:       2020/8/28 - 上午 10:37
 * author:     wangkanglu
 * version:    V1.0
 */
public class SessionLisener implements HttpSessionAttributeListener {
  
    @Override
    public void attributeAdded(HttpSessionBindingEvent event) {
        String name = event.getName();
        Object value = event.getValue();
        System.out.println("session中添加【"+name+"】属性了。。。。。值是:【"+value+"】");
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent event) {
        String name = event.getName();
        Object value = event.getValue();
        System.out.println("session中移除【"+name+"】属性了。。。。。值是:【"+value+"】");
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent event) {
        String name = event.getName();
        //这是旧值
        Object value = event.getValue();
        //这是新的值
        Object attribute = event.getSession().getAttribute(name);
        System.out.println("session中修改替换【"+name+"】属性了。。。。。旧值是:【"+value+"】新的值是【"+attribute+"】");
    }
}

在jsp中:

<%
    session.setAttribute("user","admin");
    Thread.sleep(3000);
    session.setAttribute("user","lisi");
    Thread.sleep(3000);
    session.removeAttribute("user");
%>

结果:

Spring Authorization Server PKCE刷新token springsession token_服务器_07

 

4:session钝化和活化监听器(HttpSessionActivationListener)

所谓钝化session,就是把session通过序列化的方式保存到硬盘文件中。当用户再使用session时,Tomcat还会把钝化的对象再活化session,所谓活化就是把硬盘文件中的session在反序列化回内存。当session被Tomcat钝化时,session中存储的对象也被纯化,当session被活化时,也会把session中存储的对象活化

javabean代码:

package com.wkl.bean;

import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionEvent;
import java.io.Serializable;

/**
 * Description:
 * 这两个监听器都不用在web.xml中注册
 * HttpSessionActivationListener:活化,钝化监听器
 * HttpSessionAttributeListener:监听对象调用的监听器
 *
 * Date:       2020/8/31 - 下午 3:22
 * author:     wangkanglu
 * version:    V1.0
 */
public class User implements Serializable,HttpSessionActivationListener{
    //session将要钝化
    @Override
    public void sessionWillPassivate(HttpSessionEvent se) {
        System.out.println("我【"+this+"】要和session一起被钝化了。。。。。。");
    }

    //sssion活化了
    @Override
    public void sessionDidActivate(HttpSessionEvent se) {
        System.out.println("我【"+this+"】要和session又活了。。。。。。");
    }
}

在jsp中将javabean加入session中;

Spring Authorization Server PKCE刷新token springsession token_java_08

 

当关闭服务器时发生钝化:

Spring Authorization Server PKCE刷新token springsession token_服务器_09

当再次开启服务器时他们又会活化过来

 

5:session的绑定对象和解绑监听器

他和session域中属性变化的监听器的区别就是;绑定属性监听器的范围小;这个只监听这个对象;

package com.wkl.bean;

import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import java.io.Serializable;

/**
 * Description:
 * 这两个监听器都不用在web.xml中注册
 * HttpSessionActivationListener:活化,钝化监听器
 * HttpSessionAttributeListener:监听对象调用的监听器
 *
 * Date:       2020/8/31 - 下午 3:22
 * author:     wangkanglu
 * version:    V1.0
 */
public class User implements Serializable,HttpSessionAttributeListener{
   

    @Override
    public void attributeAdded(HttpSessionBindingEvent event) {
        System.out.println("user绑定了。。。。");
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent event) {
        System.out.println("user移除了。。。。");
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent event) {
        System.out.println("user替换了。。。。");
    }
}

二:cookie

1:Cookie(总结:浏览器端保存少量数据的一种技术;)

1.1:什么是 Cookie?

1、Cookie 翻译过来是饼干的意思。
2、Cookie 是服务器通知客户端保存键值对的一种技术。
3、客户端有了 Cookie 后,每次请求都发送给服务器。
4、每个 Cookie 的大小不能超过 4kb

5、一个cookie是一个名字-值对,可以保存多个的

1.2:特点

1:保存少量

2:都是纯文本

3:保存的当前网站的cookie;每次访问网站都会携带过去(该网站所有的cookie);如果我们是浏览器;那么银行卡就是银行网站给我们的cookie;

1.3:cookie的有效时间

1:默认是会话期间有效(浏览器只要不关,cookie就在;cookie存在于浏览器的进程中)

2:public void setMaxAge(int expiry) 来设置cookie的有效时间;

expiry - 一个指明cookie的最大生存时间的以秒计时的整数。

               如果是一个负值,意味着cookie不会被存储;

              如果为零,则删除该cookie。

Cookie cookie = new Cookie("test","wkl");
        cookie.setMaxAge(10);
        response.addCookie(cookie);

2:如何创建 Cookie

Spring Authorization Server PKCE刷新token springsession token_监听器_10

请求返回的响应通过在请求头中的设置;让浏览器来保存cookie; 

Spring Authorization Server PKCE刷新token springsession token_服务器_11

 

package com.wkl.servlet;
 
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
 
/**
 * Description:
 * Date:       2020/6/14 - 下午 9:10
 * author:     wangkanglu
 * version:    V1.0
 */
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 它会同时设置服务器和客户端都使用 UTF-8 字符集,还设置了响应头
        // 此方法一定要在获取流对象之前调用才有效
        resp.setContentType("text/html; charset=UTF-8");
        PrintWriter writer = resp.getWriter();
        writer.write("我知道了,回去吧");
        //1 创建 Cookie 对象
        Cookie cookie = new Cookie("key4", "value4");
        //2 通知客户端保存 Cookie
        resp.addCookie(cookie);
        //1 创建 Cookie 对象
        Cookie cookie1 = new Cookie("key5", "value5");
        //2 通知客户端保存 Cookie
        resp.addCookie(cookie1);
        resp.getWriter().write("Cookie  创建成功");
 
    }
 
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("HelloServlet的post方法被请求了。。。");
    }
 
}

3:服务器如何获取 Cookie

服务器获取客户端的 Cookie 只需要一行代码:req.getCookies():Cookie[]

Spring Authorization Server PKCE刷新token springsession token_java_12

package com.wkl.servlet;
 
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
 
/**
 * Description:
 * Date:       2020/6/14 - 下午 9:10
 * author:     wangkanglu
 * version:    V1.0
 */
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 它会同时设置服务器和客户端都使用 UTF-8 字符集,还设置了响应头
        // 此方法一定要在获取流对象之前调用才有效
        resp.setContentType("text/html; charset=UTF-8");
        PrintWriter writer = resp.getWriter();
        writer.write("我知道了,回去吧");
 
        //获取cookie
        Cookie[] cookies = req.getCookies();
        for (Cookie cookie : cookies) {
         getName 方法返回 Cookie 的 key (名)
         getValue 方法返回 Cookie 的 value 值
        resp.getWriter().write("Cookie[" + cookie.getName() + "=" + cookie.getValue() + "] <br/>");
        
         }
        
        //1 创建 Cookie 对象
        Cookie cookie = new Cookie("key4", "value4");
        //2 通知客户端保存 Cookie
        resp.addCookie(cookie);
        //1 创建 Cookie 对象
        Cookie cookie1 = new Cookie("key5", "value5");
        //2 通知客户端保存 Cookie
        resp.addCookie(cookie1);
        resp.getWriter().write("Cookie  创建成功");
 
    }
 
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("HelloServlet的post方法被请求了。。。");
    }
 
}

4:Cookie 值的修改(同名cookie覆盖)

方案一:
1、先创建一个要修改的同名(指的就是 key)的 Cookie 对象
2、在构造器,同时赋于新的 Cookie 值。
3、调用 response.addCookie( Cookie );

Cookie cookie = new Cookie("key1","newValue1");
// 3 、调用 response.addCookie( Cookie ); 通知 客户端 保存修改
resp.addCookie(cookie);

方案二:
1、先查找到需要修改的 Cookie 对象
2、调用 setValue()方法赋于新的 Cookie 值。
3、调用 response.addCookie()通知客户端保存修改

方案二:
// 1 、先查找到需要修改的 Cookie 对象
Cookie cookie = CookieUtils.findCookie("key2", req.getCookies());
if (cookie != null) {
// 2 、调用 setValue() 方法赋于新的 Cookie 值。
cookie.setValue("newValue2");
// 3 、调用 response.addCookie() 通知客户端保存修改
resp.addCookie(cookie);
}

5:浏览器查看cookie

Spring Authorization Server PKCE刷新token springsession token_服务器_13

 

6:Cookie 生命控制 

setMaxAge()
正数,表示在指定的秒数后过期
负数,表示浏览器一关,Cookie 就会被删除(默认值是-1)
零,表示马上删除 Cookie

Cookie cookie = new Cookie("life3600", "life3600");
cookie.setMaxAge(60 * 60); // 设置 Cookie 一小时之后被删除。无效
resp.addCookie(cookie);
resp.getWriter().write(" 已经创建了一个存活一小时的 Cookie");
// 先找到你要删除的 Cookie 对象
Cookie cookie = CookieUtils.findCookie("key4", req.getCookies());
if (cookie != null) {
// 调用 setMaxAge(0);
cookie.setMaxAge(0); // 表示马上删除,都不需要等待浏览器关闭
// 调用 response.addCookie(cookie);
resp.addCookie(cookie);
resp.getWriter().write("key4 的 的 Cookie  已经被删除");
}
Cookie cookie = new Cookie("defalutLife","defaultLife");
cookie.setMaxAge(-1);// 设置存活时间
resp.addCookie(cookie);

三:Session会话

1:什么是 Session  会话?

1、Session 就一个接口(HttpSession)。
2、Session 就是会话。它是用来维护一个客户端和服务器之间关联的一种技术。
3、每个客户端都有自己的一个 Session 会话。
4、Session 会话中,我们经常用来保存用户登录之后的信息。

2:如何创建 Session  和获取(id  号, 是否为新)

如何创建和获取 Session。它们的 API 是一样的。

2.1request.getSession()

第一次调用是:创建 Session 会话
之后调用都是:获取前面创建好的 Session 会话对象。

2.2:isNew(); 判断到底是不是刚创建出来的(新的)

true 表示刚创建
false 表示获取之前创建
每个会话都有一个身份证号。也就是 ID 值。而且这个 ID 是唯一的。

2.3:getId() 得到 Session 的会话 id 值。

3:Session 域数据的存取

3.1:向Session中存数据

req.getSession().setAttribute("key1", "value1");
resp.getWriter().write(" 已经往 Session  中保存了数据");

3.2:从Session中取数据

Object attribute = req.getSession().getAttribute("key1");
resp.getWriter().write("从 从 Session  中获取出 key1  的数据是:" + attribute);

4:Session 生命周期控制

  • public void setMaxInactiveInterval(int interval) 设置 Session 的超时时间(以秒为单位),超过指定的时长,Session就会被销毁。

值为正数的时候,设定 Session 的超时时长。
负数表示永不超时(极少使用)

  • public int getMaxInactiveInterval()获取 Session 的超时时间
  • public void invalidate() 让当前 Session 会话马上超时无效

4.1Session 默认的超时时长是多少!Session 默认的超时时间长为 30 分钟。

因为在Tomcat服务器的配置文件web.xml中默认有以下的配置,它就表示配置了当前Tomcat服务器下所有的Session
超时配置默认时长为:30 分钟。

<session-config>
<session-timeout>30</session-timeout>
</session-config>

4.2:修改默认Session超时时间

如果说。你希望你的 web 工程,默认的 Session 的超时时长为其他时长。你可以在你自己的 web.xml 配置文件中做
以上相同的配置。就可以修改你的 web 工程所有 Seession 的默认超时时长

<!-- 表示当前 web 工程。创建出来 的所有 Session 默认是 20 分钟 超时时长 -->
<session-config>
<session-timeout>20</session-timeout>
</session-config>

4.3:设置Session超时时间

如果你想只修改个别 Session 的超时时长。就可以使用上面的 API。setMaxInactiveInterval(int interval)来进行单独的设置。
session.setMaxInactiveInterval(int interval)单独设置超时时长。

Spring Authorization Server PKCE刷新token springsession token_服务器_14

// 先获取 Session 对象
HttpSession session = req.getSession();
// 设置当前 Session3 秒后超时
session.setMaxInactiveInterval(3);
resp.getWriter().write(" 当前 Session  已经设置为 3  秒后超时");

5:  浏览器和 Session 之间关联的技术内幕

Session 技术,底层其实是基于 Cookie 技术来实现的

Spring Authorization Server PKCE刷新token springsession token_java_15

四:cookie、session会话机制

1:我们和服务器交互期间;可能存放一些数据;服务器专门为每个会话创建一个map(session);这个map用来保存数据

2:100个会话会有100个session,每次创建session的时候会有一个唯一标识(jsessionid,会话id)

利用浏览器每次请求都会带上所有的cookie的特性;

服务器只要创建一块能保存数据的map,给map一个唯一标识(jsessionid),创建好以后命令浏览器cookie保存这个id;

以后浏览器只要访问就会带上这个jsessionid;服务器按照这个标识;找到存储的数据;

Spring Authorization Server PKCE刷新token springsession token_java_16

注意:

1:会话关闭,默认是coolie没了;挺过cookie持久化技术继续找到之前的sessionid;

2:session失效;自动超时或者手动失效

五:令牌机制

防止表单重新提交;

原理:在页面加载时,一个token放在session中,另一个用form提交传递到后台,后台接收到两个token进行对比,相同则是第一次提交,清空token

1:页面代码:

<h1>添加商品的页面</h1>
        <%
            String token = UUIDUtils.getUUID();
            session.setAttribute("token", token);
        %>
        <form action="${ pageContext.request.contextPath }/ProductAddServlet" method="post">
        <input type="hidden" name="token" value="${ token }"/>

2:后台代码:

// 判断是否是重复提交:
        String token1 = (String)request.getSession().getAttribute("token");
        String token2 = request.getParameter("token");
        // 清空session中的令牌:
        request.getSession().removeAttribute("token");
        if(!token2.equals(token1)){
            request.setAttribute("msg", "亲!您已经提交过!请不要重复提交了!");
            request.getRequestDispatcher("/jsp/msg.jsp").forward(request, response);
            return;
        }

六:token机制认证方法

使用token机制的身份验证方法,在服务器端不需要存储用户的登录记录。大概的流程:

客户端使用用户名和密码请求登录。
服务端收到请求,验证用户名和密码。
验证成功后,服务端会生成一个token,然后把这个token发送给客户端。
客户端收到token后把它存储起来,可以放在cookie或者Local Storage(本地存储)里。
客户端每次向服务端发送请求的时候都需要带上服务端发给的token。
服务端收到请求,然后去验证客户端请求里面带着token,如果验证成功,就向客户端返回请求的数据。