Session的工作原理和应用详解

1. Session 原理

1.1 Session 背景信息

服务器状态管理技术,将状态信息保存在服务器端。
是sun公司定义的一个接口。

1.2 Session 工作原理

在这里插入图片描述
执行流程:

  1. 第一次请求,请求头中没有jsessionid的cookie,当访问到对应的servlet资源时,执行到getSession()会创建HttpSession对象;进而响应时就将session的id作为cookie的value,响应到浏览器 Set-cookie:jsessionid=xxxx;
  2. 再一次请求时,http请求中就有一个cookie:jsessionid=xxxx信息,那么该servlet就可以通过getSession()获取到jsessionid在服务器内查找对应的session对象,有就使用,无就创建。

1.3 Session 创建、获取、销毁

// 获取session对象,服务器底层创建Session
HttpSession session = request.getSession();
// 获取session对象的唯一标识:sessionID (JSESSIONID=E925DE1EF00F7944537C01A3BC0E2688)
String jsessionid = session.getId();
// 销毁session对象中的jsessionid
session.invalidate();

1.4 Session 共享范围

http域对象之一,服务器中可跨资源共享数据。

// 往 session 中存储 msg
HttpSession session = request.getSession();
session.setAttribute("msg", "helloSession");
// 获取 msg
HttpSession session = request.getSession();
Object msg = session.getAttribute("msg");
// 删除域对象中的数据
session.removeAttribute("msg");

1.5 Session 生命周期

一般都是默认值 30 分钟,无需更改。
取决于 Tomcat 中 web.xml 默认配置:

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

Session生命周期结束时机:

  • 浏览器关闭:销毁Cookie中的jsessionid=xxx,原session对象会保留默认30min后才销毁,30分钟后为新的session;
  • session销毁:主动调用 session.invalidate() 方法后,立即将session对象销毁,再次访问时会创建新的session。

1.6 HTTP请求中 4 大共享数据方式对比

在这里插入图片描述
在这里插入图片描述

2. Session 应用

2.1 案例:使用验证码登陆和共享用户信息

表单数据:

<form action="/demo/login" method="post">
    账户:<input type="text" name="username"  /> <br>
    密码:<input type="password" name="password" /> <br>
    验证:<input type="text" name="validateCode" /><img src="/demo/createCode"><br>
    <button type="submit">登陆</button>
</form>

验证码图片生成:

@WebServlet(name = "CreateCodeServlet", urlPatterns = "/createCode")
public class CreateCodeServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int width = 60;//定义图片宽度
        int height = 32;//定义图片高度
        //创建图片对象
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //创建画笔对象
        Graphics g = image.getGraphics();
        //设置背景颜色
        g.setColor(new Color(0xDCDCDC));
        g.fillRect(0, 0, width, height);//实心矩形
        //设置边框
        g.setColor(Color.black);
        g.drawRect(0, 0, width - 1, height - 1);//空心矩形

        Random rdm = new Random();
        //画干扰椭圆
        for (int i = 0; i < 50; i++) {
            int x = rdm.nextInt(width);
            int y = rdm.nextInt(height);
            g.drawOval(x, y, 0, 0);
        }
        //产生随机字符串
        String hash1 = Integer.toHexString(rdm.nextInt());
        //生成四位随机验证码
        String capstr = hash1.substring(0, 4);
        //将产生的验证码存储到session域中,方便以后进行验证码校验!
        request.getSession().setAttribute("existCode", capstr);
        System.out.println(capstr);
        g.setColor(new Color(0, 100, 0));
        g.setFont(new Font("Candara", Font.BOLD, 24));
        g.drawString(capstr, 8, 24);
        g.dispose();
        //将图片响应到浏览器
        response.setContentType("image/jpeg");
        OutputStream strm = response.getOutputStream();
        ImageIO.write(image, "jpeg", strm);
        strm.close();
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

登陆 Servlet:

@WebServlet(name = "LoginServlet", urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        // 获取输入的验证码
        String validateCode = request.getParameter("validateCode");
        // 将输入的验证码和产生的随机验证码进行校验
        String existCode = (String) request.getSession().getAttribute("existCode");
        if (validateCode.equals(existCode)) {
            String username = request.getParameter("username");
            String password = request.getParameter("password");

            UserDao userDao = new UserDaoImpl();
            Userinfo inputUserinfo = new Userinfo();
            inputUserinfo.setUsername(username);
            inputUserinfo.setPassword(password);
            try {
                Userinfo existUserinfo = userDao.login(inputUserinfo);
                System.out.println(existUserinfo);
                if (null == existUserinfo) {
                    // 登陆失败,跳转登陆页面,转发
                    request.getRequestDispatcher("/login.html").forward(request, response);
                } else {
                    // 登陆成功,跳转到首页,重定向
                    request.getSession().setAttribute("existUser", existUserinfo);
                    response.sendRedirect("/demo/show");
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } else {
            // 校验不通过,跳转到登陆页面
            request.getRequestDispatcher("/login.html").forward(request, response);
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

展示 Servlet:

@WebServlet(name = "ShowIndexServlet", urlPatterns = "/show")
public class ShowIndexServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        Userinfo existUserinfo = (Userinfo) request.getSession().getAttribute("existUser");
        if (null != existUserinfo) {
            // 在登陆状态
            response.getWriter().write("欢迎回来," + existUserinfo.getUsername());
        } else {
            // 不在登陆状态,根据需求:①提示 ②跳转到登陆页
            //response.getWriter().write("您还未登陆,<a href='/demo/login.html'>请登陆</a>");
            response.sendRedirect("/demo/login.html");
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
发布了327 篇原创文章 · 获赞 312 · 访问量 67万+

猜你喜欢

转载自blog.csdn.net/sinat_36184075/article/details/105674613
今日推荐