在学习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();
}
}
只是自己的想法 如果有出入,请指出!