众所周知,每当我们尝试登录至某种网络应用时,总会被提示输入账户密码以进行验证。然而,你们是否曾疑惑过,为何当我们成功完成登录后,服务器竟然能够判断出我们的身份,并据此对我们开放相应的访问权限呢?其实,问题就源于我们在登录过程中所保留在服务器上的 session 以及存在于客户端即我们浏览器内的 cookie。
以我们日常使用的博客平台为例,只要我们成功登录后,无需再次注销登录便可自由评论他人发表的文章。那么,在此过程中,服务器又是如何实现这样的用户权限管理功能呢?接下来便是本堂课程所侧重阐述的主题——session。
图片来源于网络
在诸多网络应用程序的设计与开发过程中,为了确保用户身份的持续有效及其状态信息的保存与延续,我们常常采用会话 (Session)这种方式来追踪用户的登录状态及其他相关信息。会话是一项在客户端和服务器之间维持数据状态的关键技术手段,它使得服务器得以识别特定使用者并始终保持其登录状态不变。
之前我们已经搭建过了一个servlet应用程序,所以说关于如何搭建一个程序的话,我们这里就不必再阐述了,大家可以直接参考我上一篇讲的文章去进行一个搭建。
Java技术中的经典之作:Servlet的实践运用 juejin.cn/post/731100…
我们首先来看一个session的例子。这里我们新建一个MySession 的类。继承至HttpServlet 类,方便我们后续在Http中进行一个调用。
public class MySession extends HttpServlet {
/**
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
HttpSession session = req.getSession();
String id = session.getId();
System.out.println(id);
System.out.println(session.getAttribute("name"));
PrintWriter writer = resp.getWriter();
writer.print("你好");
writer.close();
}
}
紧接着我们再新建一个类,继承我们刚刚写的这个类。
@WebServlet(urlPatterns = "/mySession")
public class MySession2 extends MySession {
/**
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.setAttribute("name","masiyi");
super.doGet(req, resp);
}
}
之后我们就可以启动浏览器去访问我们的地址。
http://localhost:8080/mySession
这里就可以看到我们已经成功的在浏览器上看到了你好两个字。
我们可以看到。刚刚我们访问浏览器的时候,我们在后台已经输出了对应的信息,一个是这个会话的id,一个是我们设置的值
再返回到我们MySession2这个类里面去看一下。
HttpSession session = req.getSession();
session.setAttribute("name","masiyi");
super.doGet(req, resp);
首先我们要知道的是浏览器只要不关我们访问这个地址,它的Session就会是一个Session,我们看刚刚这个类里面我们拿出了他的session之后,给session设置了一个值。之后我们再去调用它父类的doget方法。
resp.setContentType("text/html;charset=UTF-8");
HttpSession session = req.getSession();
String id = session.getId();
System.out.println(id);
System.out.println(session.getAttribute("name"));
PrintWriter writer = resp.getWriter();
writer.print("你好");
writer.close();
父类里面拿到sessionID之后进行一个输出,我们再输出我们在子类里面设置的name的值。最后我们拿到PrintWriter 给他返回到浏览器上面去。
我们现在已经看到了。每次发生一次会话的时候,他就会新建一个session。那么大家有没有想过除了我们手动关闭浏览器?而关闭这个session之外,我们可以在代码中手动关闭这个session吗?再想一个问题,我们关闭之后的session。跟之前的session会是一个session吗?所以说我们再次写两个类来验证我们刚刚的问题。
@WebServlet(urlPatterns = "/mySession3")
public class MySession3 extends HttpServlet {
/**
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(req.getRequestId());
HttpSession session = req.getSession();
session.setAttribute("name", "masiyi3");
//失效
// session.setMaxInactiveInterval(3);
//失效
// session.invalidate();
String uri = resp.encodeURL("/mySession4");
resp.sendRedirect(uri);
System.out.println(uri);
System.out.println("setAttribute");
System.out.println(session.getId());
}
}
-
session.setMaxInactiveInterval(3);:这行代码用于设置会话的最大非活动时间间隔,单位为秒。在这个例子中,3代表3秒,意味着如果用户在3秒内没有活动(例如没有请求服务器),会话将自动失效。
-
session.invalidate();:这行代码用于手动使当前会话失效,即立即终止当前会话并清除与之相关的所有数据。通常在用户注销或需要强制用户退出登录时使用。
当我们在浏览器中访问http://localhost:8080/mySession3
这个地址的时候,我们会发现它跳了一下,然后就返回到session4去了,这个时候我们的后台会打印什么呢?我们可以看一下。
其实我们通过上面的结果知道了。我们在不关闭的情况下,任意重定向跳转之后,他们的section其实还是一个,他们的attribute值是可以相互传递的。
但是我们手动关闭了这个session之后,我们再次访问老地址,我们就会发现。他们的session其实不是一样的。他们的值也是互不相通的。
读过我前面文章的同学应该知道,我其实正在写一个spring security的入门专栏。所以说这节加上前面的四节其实都是spring security的基础。也就是说你要想了解spring security你必须要了解这五篇文章中所学的知识。所以我把他们全都放在一个项目里面。项目的地址就在 gitee.com/WangFuGui-M…
文章 | 链接 |
---|---|
Java技术中的经典之作:Servlet的实践运用 | juejin.cn/post/731100… |
介绍一下傻傻分不清的两个兄弟:过滤器和拦截器之过滤器 | juejin.cn/post/731160… |
介绍一下傻傻分不清的两个兄弟:过滤器和拦截器之拦截器 | juejin.cn/post/731236… |
Java里的线程神器:ThreadLocal | juejin.cn/post/731397… |
在后面的spring security的进阶专栏里面。我们会把这五节课的知识全部整合在一起。这就是我写这五节课的目的。如果大家对此有兴趣的话,欢迎关注点赞。加评论。我们spring security的进阶专栏见。