• Session详解(重点)


    什么是Session:

    (1)服务器会给每一个用户(浏览器)创建一个Session对象

     比如我们现在都去访问百度,我们使用双核浏览器和谷歌浏览器同时访问百度这个网址,百度那边会有两个session,因为浏览器不一样,但是只要在一个浏览器里面一直用百度的话,就没有区别。我们用两个浏览器相当于是模拟两个客户端。

     (2)一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在。

    (3)用户登录之后,整个网站它都可以访问。(保存用户的信息、保存购物车的信息)

    比如我们登录csdn之后,csdn网站上的内容都可以进行点击,不用重复登录。可以访问该用户权限下的所有网页。

    如果退出用户之后,其中的好多页面都需要我们进行登录之后才可以使用。

     Session和Cookie的区别:

    首先我们进行创建一个session类:然后再按住ctrl键的同时点击HttpSession。我们进入Session的源码界面,点开Struct进行查看:

     进入源码界面如下所示:

     我们进行分析源码:
    得到一个唯一的标识符:

     public String getId();

    获得ServletContext:(web对象几乎都可以获得ServletContext,ServletContext代表整个web服务)

    public ServletContext getServletContext();

    得到一个节点:(获得这个名字)

    public Object getAttribute(String name);

    有get就有set:(设置值的方法)

     public void setAttribute(String name, Object value);

    移除一个指定的属性:

    public void removeAttribute(String name);

    判断是否是新的:

     public boolean isNew();

    注销:

      public void invalidate();

     setAttribute可以存很多东西 ,Object代表对象,可以存一个对象。

    我们设计代码如下所示:

    我们在设计代码的过程中,需要重写doGet和doPost方法,因为httpServlet中的doGet和doPost方法只有原生的req和resp,实现页面的数据交互的本质是重写方法,操作req和resp。

    1. package com.rgf.servlet;
    2. import javax.servlet.ServletException;
    3. import javax.servlet.http.HttpServlet;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. import javax.servlet.http.HttpSession;
    7. import java.io.IOException;
    8. public class SessionDemo01 extends HttpServlet {
    9. @Override
    10. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    11. //解决乱码问题
    12. req.setCharacterEncoding("utf-8");
    13. //响应
    14. resp.setCharacterEncoding("utf-8");
    15. resp.setContentType("text/html;charset=utf-8");
    16. //得到Session
    17. HttpSession session = req.getSession();
    18. //给Session中存东西
    19. session.setAttribute("name","蕾峰编程");
    20. //获取session的ID
    21. String sessionId = session.getId();
    22. //判断Session是不是新创建的
    23. if(session.isNew()){
    24. resp.getWriter().write("session创建成功,ID:"+sessionId);
    25. }else {
    26. resp.getWriter().write("session已经在服务器中存在了,ID:"+sessionId);
    27. }
    28. }
    29. @Override
    30. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    31. doGet(req, resp);
    32. }
    33. }

    我们进行设计web.xml:

    1. SessionDemo01
    2. com.rgf.servlet.SessionDemo01
    3. SessionDemo01
    4. /s1

    运行之后界面如下所示:

     session之所以已经存在了,是因为tomcat启动的时候自动访问了该站点,所以就已经存在了

    我们点开开开发者工具进行查看:

    我们发现在请求的时候我们带了一个Cookie, 

    session其实是浏览器访问此服务器任何一个页面的时候都自动创建的,所以我们在访问了其他页面后,在访问session页会发现已存在。

    我们进行单独对象进行分包的时候,一个实体类,两个关键词。即为entity(又叫pojo)最原始的java类

    我们进行分包如下所示:

     我们点击Compact Middle Packages,如下所示:

    之后我们创建pojo包,在该包下进行创建实体类:

     之后我们再创建一个类,进行提取session里面的东西:由于我们已经再SessionDemo01里面已经在session里面添加了东西,现在我们利用sessionDemo02进行提取session里面的东西:

    我们所设计的代码如下所示:

    1. package com.rgf.servlet;
    2. import sun.net.httpserver.HttpServerImpl;
    3. import javax.servlet.ServletException;
    4. import javax.servlet.http.HttpServlet;
    5. import javax.servlet.http.HttpServletRequest;
    6. import javax.servlet.http.HttpServletResponse;
    7. import javax.servlet.http.HttpSession;
    8. import java.io.IOException;
    9. public class SessionDemo02 extends HttpServlet {
    10. @Override
    11. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    12. //解决乱码问题
    13. req.setCharacterEncoding("utf-8");
    14. //响应
    15. resp.setCharacterEncoding("utf-8");
    16. resp.setContentType("text/html;charset=utf-8");
    17. //得到Session
    18. HttpSession session = req.getSession();
    19. //从Session中取出东西,我们将其new一个对象,然后出现Object,我们进行强制转换,点击alt+enter。
    20. String name = (String) session.getAttribute("name");
    21. System.out.println(name);
    22. }
    23. @Override
    24. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    25. doGet(req, resp);
    26. }
    27. }

    我们在web.xml里面进行注册:

    1. SessionDemo02
    2. com.rgf.servlet.SessionDemo02
    3. SessionDemo02
    4. /s2

    我们进行运行之后,发现如下所示:

    出现空白,这个时候我们在控制台进行查看的时候,发现输出为null。

    我们先进行访问 http://localhost:9571/Cookie_war/s1 的时候,之后再进行访问http://localhost:9571/Cookie_war/s2的时候,这个时候我们发现控制台输出我们在s1里面的session存入的东西。

     我们进行创建了Person类,如下所示:

    1. package com.rgf.pojo;
    2. public class Person {
    3. private String name;
    4. private int age;
    5. //有参无参构造:Constructor
    6. //有参构造:
    7. public Person(String name, int age) {
    8. this.name = name;
    9. this.age = age;
    10. }
    11. //无参构造:Select None
    12. public Person() {
    13. }
    14. //ctrl+o为重写方法
    15. //鼠标右键Generate,进行重写get和set方法。
    16. public String getName() {
    17. return name;
    18. }
    19. public void setName(String name) {
    20. this.name = name;
    21. }
    22. public int getAge() {
    23. return age;
    24. }
    25. public void setAge(int age) {
    26. this.age = age;
    27. }
    28. //为了调试输出方面,还会加toString:
    29. @Override
    30. public String toString() {
    31. return "Person{" +
    32. "name='" + name + '\'' +
    33. ", age=" + age +
    34. '}';
    35. }
    36. }

    我们在sessionDemo01该类里面存入session的代码修改如下所示:

    1. // //给Session中存入东西
    2. session.setAttribute("name",new Person("蕾峰编程",22));

    之后再SessionDemo02里面往出取session的代码如下所示:

    1. Person person = (Person) session.getAttribute("name");
    2. // public String toString()返回该对象的字符串表示。
    3. // 通常,ToString方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。
    4. System.out.println(person.toString());

    session不仅可以存字符串,也可以存用户的信息。

    我们进行运行之后,如下所示:

     我们发现对象也可以往里面存,也可以从里面取出来。

    我们必须先进行再SessionDemo01里面进行存之后才能再SessionDemo02里面进行取。

    我们进行注销session,我们所设计的代码如下所示:
     

    1. package com.rgf.servlet;
    2. import com.rgf.pojo.Person;
    3. import javax.servlet.ServletException;
    4. import javax.servlet.http.HttpServlet;
    5. import javax.servlet.http.HttpServletRequest;
    6. import javax.servlet.http.HttpServletResponse;
    7. import javax.servlet.http.HttpSession;
    8. import java.io.IOException;
    9. public class SessionDemo03 extends HttpServlet {
    10. @Override
    11. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    12. //解决乱码问题
    13. req.setCharacterEncoding("utf-8");
    14. //响应
    15. resp.setCharacterEncoding("utf-8");
    16. resp.setContentType("text/html;charset=utf-8");
    17. //得到Session
    18. HttpSession session = req.getSession();
    19. //取消掉我们所存入的name。
    20. session.removeAttribute("name");
    21. //注销掉session
    22. session.invalidate();
    23. }
    24. @Override
    25. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    26. doGet(req, resp);
    27. }
    28. }

    之后在web.xml里面进行注册:

    1. SessionDemo03
    2. com.rgf.servlet.SessionDemo03
    3. SessionDemo03
    4. /s3

    之后运行之后如下所示:

     我们再重新登录s1,发现如下所示:

    说明以前的session已经被注销了。 

    我们知道session是一个浏览器对应一个session,我们利用其他浏览器进行对比如下:

     我们发现这两个浏览器里面所使用的session的ID不同。我们再进行回车,发现他们的ID还是那个样子,没有发生变化。

    我们先利用s3,进行session的注销,之后我们访问s2,发现如下所示:

     出现空指针异常,这个空指针异常是person空指针异常,是因为session中的键name不存在导致的。注销之后访问s2正常会更新ID。

    我们重新访问s1后,我们发现如下所示:

    我们发现这个ID与此前的不一样,一旦注销之后,浏览器就会产生一个新的session。 

    我们再双核浏览器进行同样的操作:

    我们发现该ID也发生了变化。 这种方式是手动注销的方式。

    当用户登录的时候,如果一两天还没有用的话,我们有自定失效时间。我们在web.xml里面进行设置如下所示:

    1. 1

    如果我们所设置失效时间长的话会因为如果用户量特别大,服务器上全是session,会容易崩。

    我们在更好的网站一般采用cookie,cookie会持久化的保存到客户端,浏览器也有清除cookie的作用,点击设置,进入清除浏览数据,如下所示:

     但是我们建议一般不删除cookie.

    我们进行测试看是否在我们所设置的session会在一分钟后失效:

     我们进行刷新如下所示:

    发现出现了一个新的session。

    Session和Cookie的区别:
    Cookie是把用户的数据写给用户的浏览器,浏览器保存。(可以保存多个)

    Session把用户的数据写到用户独占Session中,服务器端保存。(保存重要的信息,减少服务器资源的浪费)

    Session对象由服务器创建

    session使用场景:

    (1)保存一个登录用户的信息;(用户登录之后,只要不关掉浏览器,都在session里面,都可以去享受他的服务,无论跳到哪个网页,他的信息都会存在)

    (2)购物车信息

    (3)在整个网站中经常会使用的数据,我们将它保存在Session中。

    使用session的代码如下所示:

    将东西存入session:

    1. package com.rgf.servlet;
    2. import com.rgf.pojo.Person;
    3. import javax.servlet.ServletException;
    4. import javax.servlet.http.*;
    5. import java.io.IOException;
    6. public class SessionDemo01 extends HttpServlet {
    7. @Override
    8. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    9. //解决乱码问题
    10. req.setCharacterEncoding("utf-8");
    11. //响应
    12. resp.setCharacterEncoding("utf-8");
    13. resp.setContentType("text/html;charset=utf-8");
    14. //
    15. // //得到Session
    16. HttpSession session = req.getSession();
    17. // //给Session中存入东西
    18. session.setAttribute("name",new Person("蕾峰编程",22));
    19. //获取session的ID
    20. String sessionId = session.getId();
    21. //判断Session是不是新创建的
    22. if(session.isNew()){
    23. resp.getWriter().write("session创建成功,ID:"+sessionId);
    24. }else {
    25. resp.getWriter().write("session已经在服务器中存在了,ID:"+sessionId);
    26. }
    27. //Session创建的时候做了什么事情:
    28. //session在创建的时候带了一个cookie,而且服务器把该cookie响应给客户端了。
    29. //Cookie cookie = new Cookie("JSESSIONID",sessionId);
    30. // resp.addCookie(cookie);
    31. }
    32. @Override
    33. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    34. doGet(req, resp);
    35. }
    36. }

    从session里面取东西:
     

    1. package com.rgf.servlet;
    2. import com.rgf.pojo.Person;
    3. import sun.net.httpserver.HttpServerImpl;
    4. import javax.servlet.ServletException;
    5. import javax.servlet.http.HttpServlet;
    6. import javax.servlet.http.HttpServletRequest;
    7. import javax.servlet.http.HttpServletResponse;
    8. import javax.servlet.http.HttpSession;
    9. import java.io.IOException;
    10. public class SessionDemo02 extends HttpServlet {
    11. @Override
    12. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    13. //解决乱码问题
    14. req.setCharacterEncoding("utf-8");
    15. //响应
    16. resp.setCharacterEncoding("utf-8");
    17. resp.setContentType("text/html;charset=utf-8");
    18. //得到Session
    19. HttpSession session = req.getSession();
    20. //从Session中取出东西,我们将其new一个对象,然后出现Object,我们进行强制转换,点击alt+enter。
    21. Person person = (Person) session.getAttribute("name");
    22. // public String toString()返回该对象的字符串表示。
    23. // 通常,ToString方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。
    24. System.out.println(person.toString());
    25. }
    26. @Override
    27. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    28. doGet(req, resp);
    29. }
    30. }

    所需要存入的东西:
     

    1. package com.rgf.pojo;
    2. public class Person {
    3. private String name;
    4. private int age;
    5. //有参无参构造:Constructor
    6. //有参构造:
    7. public Person(String name, int age) {
    8. this.name = name;
    9. this.age = age;
    10. }
    11. //无参构造:Select None
    12. public Person() {
    13. }
    14. //ctrl+o为重写方法
    15. //鼠标右键Generate,进行重写get和set方法。
    16. public String getName() {
    17. return name;
    18. }
    19. public void setName(String name) {
    20. this.name = name;
    21. }
    22. public int getAge() {
    23. return age;
    24. }
    25. public void setAge(int age) {
    26. this.age = age;
    27. }
    28. //为了调试输出方面,还会加toString:
    29. @Override
    30. public String toString() {
    31. return "Person{" +
    32. "name='" + name + '\'' +
    33. ", age=" + age +
    34. '}';
    35. }
    36. }

    手动注销session:

    1. package com.rgf.servlet;
    2. import com.rgf.pojo.Person;
    3. import javax.servlet.ServletException;
    4. import javax.servlet.http.HttpServlet;
    5. import javax.servlet.http.HttpServletRequest;
    6. import javax.servlet.http.HttpServletResponse;
    7. import javax.servlet.http.HttpSession;
    8. import java.io.IOException;
    9. public class SessionDemo03 extends HttpServlet {
    10. @Override
    11. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    12. //解决乱码问题
    13. req.setCharacterEncoding("utf-8");
    14. //响应
    15. resp.setCharacterEncoding("utf-8");
    16. resp.setContentType("text/html;charset=utf-8");
    17. //得到Session
    18. HttpSession session = req.getSession();
    19. //取消掉我们所存入的name。
    20. session.removeAttribute("name");
    21. //手动注销session
    22. session.invalidate();
    23. }
    24. @Override
    25. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    26. doGet(req, resp);
    27. }
    28. }

    自动注销session,会话自动过期:web.xml:

    1. 1

    我们查看cookie原理如下所示:

     我们的session原理如下所示:‘

    而对于ServletContext而言:

  • 相关阅读:
    Django模版层
    基于遗传算法GA的机器人栅格地图最短路径规划,可以自定义地图及起始点(提供MATLAB代码)
    5G移动通信网的定位技术发展趋势
    python写代码过程中的坑230915
    Vue.js3学习篇--Vue模板应用
    【笔者感悟】笔者的学习感悟【七】
    【Vue源码分析】Vue3.0的优化
    荧光素醋酸,CAS号: 96087-38-6
    Day 03 python学习笔记
    QStringList
  • 原文地址:https://blog.csdn.net/weixin_59448049/article/details/126732936