使用debug分析tomcat内存在请求转发时getSession方法的细节

  • Post author:
  • Post category:其他


在学习session时出现了一点疑惑,如果servlet调用getSession方法只是仅仅从request中得到cookie然后去找对应的JSESSIONID的话,那么为什么在请求转发中接收请求的那一个servlet的request中的cookie明明还没有JSESSIONID仍然可以从中得到正确的session对象呢?

1

2

可以看出在执行了getSession方法后生成了JSESSIONID也创建了一个与其关联的对象以key-value的形式存放在了tomcat内存中的的session集合中去管理,也在response中写入了JSESSIONID的cookie对象

3

因为是请求转发,还是上一个servlet的request对象所以仍然没有关于JSESSIONID的cookie

因此这里的response也是上一个servlet转发过来的,里边持有我们要得到的session的JSESSIONID

4

tomcat中的session集合并没有增加且session的id也没有变化说明仍然是原来的那session对象,但是按理来说如果getSession方法只是从reguest中的cookie来获取JSESSIONID的话,这里应该还会因为该reguest中没有JSESSIONID而创建一个新的session对象。

所以以上结果说明getSession方法在request的cookie中若没找到JSESSIONID则会response对象中查找SetCookie是否有JSESSIONID若仍然没有才会重新分配一个id与对象。若有则直接返回JSESSIONID对应的session对象

测试代码:

package session.work;

import utils.CookieUtils;

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

@WebServlet(urlPatterns = "/check")
public class LoginCheckServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        // 在请求转发中传的请求对象也会到下一个servlet中(保留修改后的响应头,但是会清空响应体内容)
        // 因为getSession方法会在响应头上添加JSESSIONID cookie信息所以也和响应对象一起转发给了下一个servlet
        // 这样在接收到转发信息后的servlet回复响应时才会携带该cookie信息
        resp.setContentType("text/html; charset=utf8");
        PrintWriter writer = resp.getWriter();
        if ("jason".equals(username) && "123".equals(password)) {
            // 重定向,将信息写进session中,让下一个页面获得信息并显示
            HttpSession session = req.getSession();
            System.out.println(session.getId());
            session.setAttribute("name", username);
            session.setAttribute("password", password);
            // 将cookie返回并重定向页面(浏览器会带着该cookie去访问)
//            resp.sendRedirect(req.getContextPath() + "/manager");
            // 请求转发
            req.getRequestDispatcher("/manager").forward(req, resp);
        } else {
//            resp.sendRedirect(req.getContextPath() + "/error.html");
            req.getRequestDispatcher("/error.html").forward(req, resp);
        }
    }
}

package session.work;

import utils.CookieUtils;

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

@WebServlet(urlPatterns = "/manager")
public class ManagerServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 检查请求中的JSESSIONID情况是否有合法的用户信息
        HttpSession session = req.getSession();
//        resp.setContentType("text/html; charset=utf8");
        PrintWriter writer = resp.getWriter();

        String name;
        // 若满足条件
        if ("jason".equals(name = (String) session.getAttribute("name")) &&
        "123".equals(session.getAttribute("password"))) {
            // 验证成功则返回成功界面
            writer.print("<h1>用户管理页面</h1>\n" +
                    "欢迎你:管理员 " + name);
        } else {
            // 若直接访问则直接返回登录界面
            resp.sendRedirect(req.getContextPath() + "/login.html");
        }
        writer.flush();
        writer.close();
    }
}

只是自己的想法 如果有出入,请指出!



版权声明:本文为weixin_63459454原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。