百木园-与人分享,
就是让自己快乐。

day22-web开发会话技术04

WEB开发会话技术04

14.Session生命周期

14.1生命周期说明

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

  2. 值为正数的时候,设置session的超时时长。

  3. 值为负数时,表示永不超时

  4. public int getMaxInactiveInterval()表示获取session的超时时间

  5. public void invalidate()表示让当前的session会话立即无效

  6. 如果没有调用setMaxInactiveInterval(int interval)来指定session的生命时长,Tomcat会以session的默认时长为准,session的默认时长为30分钟,可以在tomcat目录的conf目录下的web.xml中设置。

    image-20221122222712748

  7. Session的生命周期指的是:客户端两次请求的最大间隔时长,而不是累积时长。即当客户端访问了自己的session,session的生命周期将将从0开始重新计算。(指的是同一个会话两次请求之间的间隔时间)

    cookie的生命周期指的是累积时长

  8. Tomcat用一个线程来轮询会话状态,如果某个会话的空闲时间超过设定的最大值,则将该会话销毁。

    说明:在存放session对象的map中,会记录所有session对象的生命周期和session的上次被访问时间。Tomcat维护的线程每隔一定时间就会去扫描这个map,如果发现有某个session对象的上次被访问时间已超过了其生命周期,就会将其删除。如果浏览器在对应session对象没有过期的情况下去访问该session,那么这个session的上次访问时间就会被更新成最新访问的时间。

14.2案例演示1

案例演示1:session的生命周期

web.xml:

<!--CreateSession2-->
<servlet>
    <servlet-name>CreateSession2</servlet-name>
    <servlet-class>com.li.session.CreateSession2</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>CreateSession2</servlet-name>
    <url-pattern>/createSession2</url-pattern>
</servlet-mapping>

<!--ReadSession2-->
<servlet>
    <servlet-name>ReadSession2</servlet-name>
    <servlet-class>com.li.session.ReadSession2</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ReadSession2</servlet-name>
    <url-pattern>/readSession2</url-pattern>
</servlet-mapping>

CreateSession2:

package com.li.session;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;

public class CreateSession2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //System.out.println(\"CreateSession2 被调用\");
        //1.创建session
        HttpSession session = request.getSession();
        System.out.println(\"CreateSession2 sid= \" + session.getId());
        //2.设置生命周期为60秒
        session.setMaxInactiveInterval(60);
        //3.放属性
        session.setAttribute(\"u\", \"jack\");
        //4.给浏览器发送一个回复
        response.setContentType(\"text/html;charset=utf-8\");
        PrintWriter writer = response.getWriter();
        writer.print(\"<h1>创建session成功,设置生命周期为60s</h1>\");
        writer.flush();
        writer.close();
    }
}

ReadSession2:

package com.li.session;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;

public class ReadSession2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //System.out.println(\"ReadSession2 被调用\");
        //1.获取到session
        HttpSession session = request.getSession();
        System.out.println(\"ReadSession2 sid= \" + session.getId());
        //2.读取session的属性
        Object u = session.getAttribute(\"u\");
        if (u != null) {
            System.out.println(\"读取到session属性 u= \" + (String) u);
        } else {
            System.out.println(\"读取不到session属性u,说明原来的session已经被销毁了\");
        }
        //3.给浏览器发送一个回复
        response.setContentType(\"text/html;charset=utf-8\");
        PrintWriter writer = response.getWriter();
        writer.print(\"<h1>读取session成功</h1>\");
        writer.flush();
        writer.close();
    }
}
  1. redeployTomcat,首先在浏览器中访问http://localhost:8080/cs/createSession2创建session,然后在设置的60s生命周期内访问http://localhost:8080/cs/readSession2读取session,后台输出如下:

    image-20221123160535756

  2. 等待60s后,再次访问http://localhost:8080/cs/readSession2,后台输出如下:

    image-20221123160627142

    可以看到session的id和之前不一样了,说明服务器创建了新的session,原来的session因为超过了生命周期已经被销毁。

  3. 在浏览器抓包,也可以看出服务器返回了一个新的jsessionid值:

    image-20221123160842762

  4. 重新访问http://localhost:8080/cs/createSession2创建session,然后分别在其30s,70s后访问http://localhost:8080/cs/readSession2,后台输出的sid是一致的,说明session的生命周期的计算不是累积的,而是客户端两次请求的最大间隔时长。

    image-20221123161637722

14.2案例演示2

案例演示2:删除session

web.xml:

<!--DeleteSession-->
<servlet>
    <servlet-name>DeleteSession</servlet-name>
    <servlet-class>com.li.session.DeleteSession</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>DeleteSession</servlet-name>
    <url-pattern>/deleteSession</url-pattern>
</servlet-mapping>

DeleteSession:

package com.li.session;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;

public class DeleteSession extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //System.out.println(\"DeleteSession 被调用\");

        //演示如何删除session
        HttpSession session = request.getSession();
        session.invalidate();
        //如果要删除session的某个方法,使用session.removeAttribute

        //给浏览器发送一个回复
        response.setContentType(\"text/html;charset=utf-8\");
        PrintWriter writer = response.getWriter();
        writer.print(\"<h1>删除session成功</h1>\");
        writer.flush();
        writer.close();
    }
}

redeployTomcat,首先访问http://localhost:8080/cs/createSession2,创建session,然后访问http://localhost:8080/cs/deleteSession,删除此session。这时我们再访问http://localhost:8080/cs/readSession2读取session当前的sid,可以发现session已经不再是之前那个session了,说明之前创建的session已经被删除。

后台输出如下:

image-20221123164650579

15.Session经典案例-防止非法进入管理页面

需求说明:完成防止用户登录管理页面应用案例

image-20221123165722319

说明:

  1. 只要密码为666666,就认为是登录成功,用户名不限制
  2. 如果验证成功,则进入管理页面ManageServlet.java,否则进入error.html
  3. 如果用户直接访问ManageServlet.java,直接重定向到login.html。即不允许在未验证的情况下直接访问管理页面。

练习

思路:

  1. 首先在loginCheckServlet判断用户数据是否合法。如果合法,创建保存一个session,将用户数据保存到session中,并请求转发到ManageServlet。如果非法,则请求转发到error.html。

  2. 在ManageServlet中,首先获取session。如果该session中有设置的用户数据,说明在此次请求之前,创建过session,并在服务器保存了该session对象,即用户登录过,因此可以直接访问管理页面。否则,就说明此次请求之前没有创建过session,该session是新创建的,用户没有登录验证过,就重定向到login.html。

LoginCheckServlet:

package com.li.session.hw;

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

@WebServlet(name = \"LoginCheckServlet\", urlPatterns = {\"/loginCheckServlet\"})
public class LoginCheckServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /**
         * 首先在loginCheckServlet判断用户数据是否合法。
         * 1.如果合法,创建一个session,给session设置用户数据,并直接请求转发到ManageServlet
         * 2.如果非法,请求转发到error.html。
         */
        //获取表单数据
        String username = request.getParameter(\"username\");
        String pwd = request.getParameter(\"pwd\");
        if (\"666666\".equals(pwd)) {//如果数据合法
            //请求转发到ManageServlet
            HttpSession session = request.getSession();
            session.setAttribute(\"username\", username);
            //服务器来解析 /
            request.getRequestDispatcher(\"/manageServlet\").forward(request, response);
        } else {//数据非法,请求转发到error.html
            //服务器来解析 /
            request.getRequestDispatcher(\"/error.html\").forward(request, response);
        }
    }
}

ManageServlet:

package com.li.session.hw;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(name = \"ManageServlet\", urlPatterns = {\"/manageServlet\"})
public class ManageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /**
         * 在ManageServlet中,首先获取session。
         * 1.如果该session中有设置的用户数据,说明在此次请求之前,创建过session,
         *   并在服务器保存了该session对象,即用户登录过,因此可以直接访问管理页面。
         * 2.否则,就说明此次请求之前没有创建过session,该session是新创建的,
         *   用户没有登录验证过,就重定向到login.html。
         */
        HttpSession session = request.getSession();
        Object username = session.getAttribute(\"username\");
        // username=null 说明是新创建的session,说明该用户没有登录过
        if (username == null) {
            //浏览器解析的 /
            response.sendRedirect(\"/cs/login.html\");
            return;
        } else {
            //否则说明浏览器有对应的session(即已经登录验证过),可以直接访问管理页面
            //显示页面
            response.setContentType(\"text/html;charset=utf-8\");
            PrintWriter writer = response.getWriter();
            writer.print(\"<h1>用户管理页面</h1><br/>\" + \"欢迎你,管理员:\"
                    + username.toString());
            writer.flush();
            writer.close();
        }
    }
}

error.html:

<!DOCTYPE html>
<html lang=\"en\">
<head>
    <meta charset=\"UTF-8\">
    <title>登录失败</title>
</head>
<body>
<h1>登录失败</h1>
<a href=\"/cs/login.html\">点击返回重新登录</a>
</body>
</html>

login.html:

<!DOCTYPE html>
<html lang=\"en\">
<head>
    <meta charset=\"UTF-8\">
    <title>登录页面</title>
</head>
<body>
<form action=\"/cs/loginCheckServlet\" method=\"post\">
    用户名:<input type=\"text\" name=\"username\"/><br/><br/>
    密码:<input type=\"password\" name=\"pwd\"/><br/>
    <input type=\"submit\" value=\"登录\"/>
</form>
</body>
</html>
  1. redeployTomcat,在浏览器访问http://localhost:8080/cs/login.html,输入正确的密码,成功登录并显示页面。

    image-20221123192641298
    image-20221123192713505

  2. 此时如果在新标签页地址栏访问http://localhost:8080/cs/manageServlet,是可以直接显示页面的,因为之前已经登录过了。

    day22-web开发会话技术04

  3. 如果没有登录就访问http://localhost:8080/cs/manageServlet,会重定向到登录页面,无法直接访问管理页面。

    day22-web开发会话技术04


来源:https://www.cnblogs.com/liyuelian/p/16919600.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » day22-web开发会话技术04

相关推荐

  • 暂无文章