Session浅谈

2023-05-16

在web开发中,服务器可以为每个用户浏览器创建一个会话对象(Session对象),注意,一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以将用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其他程序时,其他程序可以从用户的session中取出该用户的数据,为用户服务

Session和Cookie的区别

Cookie是将用户的数据写给用户的浏览器,cookie用于在客户端保存用户信息

Session是将用户的数据写到用户独占的Session中,session用于在服务器端保存用户信息

PS:Servlet中的Session和JSP中的Session的关系

这两个session都是javax.servlet.http.HttpSession类的实例,本质上他们是一样的,servlet中需要通过request.getSession()来获取session对象,而JSP中可以直接使用,每个用户对应一个session对象。

Session对象由服务器创建,开发人员可以调用request的getSession方法得到session对象

session的生:request.getSession()    注意:request.getSession(false) 是只获取不创建session

request.getSession(); //服务器会首先检测有没有带cookie过来的session,如果有则获取session,如果发现浏览器禁用了cookie,再检测有没有带重写URL的session,有获取,上述两个都没有带过来,就会创建新的session 

session的死:如果session在30分钟不被使用(不管关不关浏览器) 会自动摧毁session 另外在web.xml文件中也可以配置session的失效时间

用配置的方式摧毁session:

<session-config>

    <session-timeout>10</session-timeout>  <!-- 10分钟内不使用自动销毁 -->

</session-config>

用代码的方式摧毁session:

session.invalidate();   //调用该方法来摧毁session

session的实现原理


session的具体实现基于cookie

request.getSession()首先用于判断服务器是否有创建session,如果没有,则创建一个session,每个session创建的时候都会有个ID值,服务器将该ID值以cookie的方式回写给浏览器,再次访问另一个程序时,cookie会带着该session的ID,所以,第二次在获取session的时候,不会创建session,而是会获取到该cookie所带的ID值对应的session。

但是该cookie没有设置有效期,所以关闭浏览器后,session也将失效。为了解决该问题,需要重写cookie,并设置该cookie的生命周期,值得一提的是,保存sessionID的cookie是一个固定的cookie,该cookie的名称为JSESSIONID,所以可以通过创建这个Cookie覆盖原来的cookie

                String cookieId = session.getId();  //获取session的ID值
Cookie cookie = new Cookie("JSESSIONID",cookieId); //重新创建该cookie,覆盖原来没有生命周期的cookie
cookie.setMaxAge(30*60); //设置cookie的生命周期为半个小时
cookie.setPath("/servlet"); 

response.addCookie(cookie); //服务器回写cookie给浏览器 覆盖之前系统的同名但无生命长度的cookie

上述代码的作用是,

当首次打开浏览器,访问一个名称为SessionBuy的servlet

public class SessionBuy extends HttpServlet {

               public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

HttpSession session = request.getSession(); //首次访问服务器,服务器创建session并将sessionID回写给cookie
session.setAttribute("product", "洗衣机"); //设置session的值

}

}

再次访问另一个名称为sessionPay的servlet

public class SessionPay extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession(false);  //给句cookie带过来的sessionID获取相应的session
out.print("您购买的额商品是: "+session.getAttribute("product")); //输出session的值

}

}

访问两个servlet的页面index.html

<html>
  <head>
    
    <title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
  </head>
  
  <body>
  <a href='/servlet/servlet/SessionBuy'>购买</a>
  <a href='/servlet/servlet/SessionPay'>付款</a>
  </body>
</html>

上述代码存在的一个问题是,创建的携带sessionID的cookie是系统默认创建的cookie,该cookie的没有setMaxAge(),即该cookie没有生命长度,一旦关闭浏览器,打开一个新的浏览器,该cookie已经不存在,下次通过sessionPay的servlet去获取session个的值时,由于此时cookie已经失效,所以获取不到session的数据

1.访问index.html页面

2.点击购买链接,访问SessionBuy

3.返回index.html,点击付款链接,将会显示购买的商品为  洗衣机

4.关闭浏览器 重新打开一个新的浏览器,点击付款链接 发现显示购买商品为 null

即先点击购买,会创建session,并自动创建一个sessionID, 该sessionID赋值给一个叫JSESSIONID的cookie,并将该cookie回写给浏览器,当再点击付款时,服务器会根据该浏览器的名称为JSESSIONID的cookie带过来的sessionid,获得购买时创建的session,并打印该session所带的值。但是JSESSIONID这个cookie是系统自己生成的,它的MaxAge值为0,也就是说当关闭浏览器重新打开一个浏览器,该cookie就不再生效,这时候直接点击付款,会发现显示的值为null。

为了解决关闭浏览器,重新打开浏览器再次获取session的值的问题,需要重新并覆盖创建系统的默认cookie,该该cookie设置一个生命周期,这样就解决了上述问题。

1.访问index.html页面

2.点击购买链接,访问SessionBuy

3.返回index.html,点击付款链接,将会显示购买的商品为  洗衣机

4.关闭浏览器 重新打开一个新的浏览器,点击付款链接 发现显示购买的商品还是 洗衣机

5.说明此时的cookie还在生效 上述问题得以解决

将上述SessionBuy的servlet的代码增加红色部分:

public class SessionBuy extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

HttpSession session = request.getSession();
String cookieId = session.getId(); //获取cookie携带的sessionID
Cookie cookie = new Cookie("JSESSIONID",cookieId); //覆盖系统默认的cookie,该cookie的名称为JSESSIONID
cookie.setMaxAge(30*60); //设置该cookie的存活期为半个小时,关闭浏览器再次打开浏览器该cookie依然存在
cookie.setPath("/servlet");
response.addCookie(cookie);  //将服务器该cookie回写给浏览器

session.setAttribute("product", "洗衣机");

}

}

URL重写

session的实现机制是cookie,通过cookie携带sessionID来标识session,但是如果浏览器禁用了cookie,该怎么办?我们需要想办法将sessionID通过另一个介质带给浏览器,这时候就需要一个新的技术,URL重写,即将sessionID加在超链接的后面

在上述代码的基础上加一个新的servlet

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
PrintWriter out = response.getWriter();

request.getSession();  //创建session
String url1 = response.encodeURL("SessionBuy"); //URL重写 通过该方法给URL后面添加一个ID
String url2 = response.encodeURL("SessionPay");
 
out.print("<a href='"+url1+"'>购买</a> ");
out.print("<a href='"+url2+"'>结账</a>");

}

URL重写 无法解决  4.关闭浏览器 重新打开一个新的浏览器,点击付款链接 发现显示购买商品为 null 这个问题

学习笔记 多有不足!!!


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Session浅谈 的相关文章

  • 在 ASP.NET MVC ViewModel 中存储模型 ID,安全问题

    在我的 MVC 应用程序中 我有一个页面供用户编辑其帐户详细信息 例如电子邮件地址 密码等 在我的数据库中 用户表保存此数据 主键是 UserId 在我创建的 ChangeAccountDetails 视图上 我传递了一个 ViewMode
  • PHP 7 用户会话问题 - 无法初始化存储模块

    在 PHP 7 0 中使用各种 PHP 框架会话驱动程序时存在错误 我最初在使用 CodeIgniter 数据库驱动程序时遇到了这个问题 并认为这是一个 CodeIgniter 问题 但后来在多个会话驱动程序和多个框架上遇到了这个问题 此时
  • 任何无需 GUI/X 会话即可使用 GreaseMonkey 脚本运行 Firefox 的方法

    我需要为第三方网站构建一个小型 监控 抓取工具 这是一个外部网站 其中包含有关我们访问者的统计信息 不幸的是 这个网站很难通过正常的 wget 机制 因为它使用了大量复杂的 JS 其中一部分是由 GWT 生成的 所以我的解决方法是创建一个
  • ExpressJS 设置/获取/使用 cookie

    无法获取请求中设置的 cookie 我设置我的cookie response cookie name My name 我想以这种方式获取我的cookie 它以前工作过 但我更改了快速配置 我不知道现在似乎是什么问题 request cook
  • 使用Rvest登录网站抓取时出现403错误

    我试图在需要登录的网站上抓取页面 但不断收到 403 错误 我已经修改了我网站的这两篇文章中的代码 使用rvest或httr登录网页上的非标准表单 https stackoverflow com questions 28418770 usi
  • Grails 在 Service 类中获取 Session 和 Management

    我对 Grails 会话有疑问 我正在考虑为我的会话处理提供一个服务类 所以我创建了一个名为 SessionService 的类 在 grails app services grails 下 class SessionService sta
  • 在sqlalchemy中跨不同模块访问相同的db.session

    我对 sqlalchemy 非常陌生 正在尝试找出如何让事情变得更干净和连接 我创建了一个 model base py 文档 在其中创建了一个会话并在表中建立了所有实体 以及关系等 我想创建另一个模块 在其中对 base py 中的实体 表
  • 如何在 Laravel 5.2 控制器中使用会话

    我登录并将用户名保留在会话中 然后刷新此页面 但会话不保留值 这是我的代码 class WelcomeCtrl extends Controller public function gotoWelcome return view welco
  • 创建持久的 php 登录 cookie 会话

    我试图让我的登录会话持续更长时间 这样人们就不会过早退出我的网站 例如 制作一篇博客文章并在提交时丢失 因为 php 的 cookie 过期了 理想情况下 我想给他们一个 2 小时的会话 他们不会注销 每次加载页面时都会刷新 下面的代码片段
  • Symfony2 - 访问被拒绝(用户未经过完全身份验证)

    我正在使用 Symfony2 开发一个网站 直到今天 登录没有问题 但现在登录时我没有正确验证 Symfony 分析器将我列为logged in as anon而不是我登录的用户 我还被重定向回登录页面而不是目标路径 登录过程由传统的登录表
  • 如何结束用户会话并确保用户已注销?

    我是 aspx 的新手 现在的问题是 因为我正在做一个支持网络的项目 所以我从用户那里登录了 我拖放登录模板 然后使用 Session Authentication username Tostring 存储当前登录用户的信息等 现在我什至使
  • 是否保证 HttpSessionListener.sessionCreated() 在任何其他线程访问新会话之前完成?

    我正在尝试将值缓存在ConcurrentHashMap in the Session 为了避免竞争条件并确保在任何线程尝试使用我的地图之前创建它 我使用HttpSessionListener sessionCreated 将地图添加到Ses
  • Laravel,2 个域中的 2 个项目同一会话

    我正在 2 个不同的域 domain1 tld 和域 2 tld 中创建 2 个项目 domain1 tld 是主要事件生成器页面 domain2 tld 是其事件之一 我想共享相同的会话 它们实际上共享相同的数据库和相同的 apache
  • 如何将 PHP 会话数据保存到数据库而不是文件系统中?

    我有两个网站 一个是 TLS 一个不是 两个都适用于同一个客户端 但我需要这些网站彼此 并且仅彼此 共享通用数据users orders accounts etc 这通常可以通过以下方式完成 SESSION数据 但我显然这些不能跨其他站点工
  • 会话过期后如何重定向到登录页面?

    我有三个 JSF 2 0 Web 模块 当会话过期时我需要重定向到登录页面 我已经尝试过使用HttpSessionListener 它正在调用sessionDestroyed 事件方法 但我无法在那里转发 重定向请求 我认为这是因为没有Ht
  • 从 iframe 访问 Session 变量

    我有一个 jsp 我在其中设置了会话变量 但是 当我尝试读取另一个 jsp 中的会话变量 user 时 该变量已加载到 iframe 同一主机 服务器等 中 然后我得到 NullPointerException 如何在 iframe 中获取
  • PassportJS - 自定义回调并将 Session 设置为 false

    是否可以使用自定义回调并禁用会话 在文档中 它显示了如何禁用会话和自定义回调 但如何组合它们 app get login function req res next passport authenticate local function
  • 如何在应用程序中创建会话对象

    在我的应用程序中 我想创建一个用于登录和注销的会话 我不知道如何使用会话 任何人都可以通过提供一些示例来帮助我 我认为会话对象应该是在应用程序开始运行时声明和初始化的静态对象 我遇到了这个问题 并决定将我的会话对象放入 utils 类中 该
  • 跨多个域的 ASP.NET 会话

    是否有合适的 NET 解决方案来在多个域上提供持久服务器会话 即 如果该网站的用户在 www site1 com 下登录 他们也将在 www site2 com 下登录 安全是我们正在开发的程序的一个问题 Thanks 它是否需要在会话中
  • session_regenerate_id 没有创建新的会话 id

    我有一个脚本 旨在完成当前会话并开始新的会话 我使用了一段代码 它在我的开发计算机上运行良好 但是 当我将其发布到生产服务器时 会话 ID 始终保持不变 以下是我重新启动会话的代码 session start SESSION array P

随机推荐

  • Linux环境安装Redis

    下载地址 xff1a http download redis io releases 安装步骤 xff1a 1 安装gcc yum install gcc 2 把下载好的redis 4 0 14 tar gz xff08 选择你自己的版本
  • Redis主从环境搭建

    首先先搭建一个Redis xff1a 搭建方法 xff1a Linux环境安装redis 1 新建一个目录 xff0c 按照上述链接中的方法再次搭建一个redis 2 搭建完后 xff0c 修改从节点的redis conf文件 2 1 修改
  • Redis集群环境搭建

    一 下载redis xff08 此处我下载的是5 0 3版本 xff09 下载地址 xff1a http download redis io releases Linux命令下载 xff1a wget http download redis
  • Jvisualvm使用及添加Visual GC组件

    只要装了jdk xff0c 就会自带这个工具 xff0c 路径位置如下 xff1a JVisualvm添加Visual GC插件 动态观察各个年代GC情况 访问地址 xff1a https visualvm github io plugin
  • Spring源码编译Java: 找不到符号 InstrumentationSavingAgent

    报错如下 xff1a 解决 xff1a 将spring context gradle文件的 下面这一行 br optional project 34 spring instrument 34 br 修改为 br compile projec
  • RabbitMQ学习(六)——消息确认机制(Confirm模式)

    在上一篇文章中我们讲解了RabbitMQ中的AMQP事务来保证消息发送到Broker端 xff0c 同时我们可以在事务之间发送多条消息 xff08 即在channel txSelect 和channel txCommit 之间发送多条消息
  • zookeeper初识

    一 节点类型 persistent 持久节点 persistent sequential 持久序号节点 ephemeral 临时节点 ephemeral sequential 临时序号节点 1 persistent 持久节点 默认创建的节点
  • xmlns:dubbo=“http://dubbo.apache.org/schema/dubbo“报错

    请先看看你有没有加dubbo的maven依赖 xff0c 官网在做这个demo的时候并没有说要加maven依赖 xff0c 所以会xml中会报红 lt beans xmlns xsi 61 34 http www w3 org 2001 X
  • tomcat 8源码环境编译

    源码下载 下载地址 xff1a https tomcat apache org download 80 cgi 配置 1 解压下载好的源码包 apache tomcat 8 5 57 src zip 2 解压好后 xff0c 在解压后的目录
  • servlet配置文件解析

    1 配置 lt servlet gt xff08 以下代码均是web xml中的 xff09 lt servlet gt lt servlet name gt FirstServlet lt servlet name gt lt servl
  • 线程基础之—线程的创建

    线程创建分三类 1 继承Thread 43 run 启动 xff1a 创建子类对象 43 对象 start 2 实现Runnable 43 run 启动 xff1a 使用静态代理 1 gt 创建真实角色 2 gt 创建代理角色 Thread
  • 死锁

    一个死锁的代码 public class Demo public static void main String args Object g 61 new Object Object m 61 new Object Goods goods
  • 多线程之任务调度

    Timer定时器类 TimerTask任务类 通过java timer timetask xff1a xff08 Spring的任务的任务调度就是通过他们实现的 xff09 在这种实现方式中 xff0c Timer类实现的是类似于闹钟的功能
  • static关键字

    在类中 xff0c 用static声明的成员变量为静态成员变量 xff0c 或者叫做 xff1a 类属性 xff0c 类变量 它为该类的公用变量 xff0c 属于类 xff0c 被该类的所有实例共享 xff0c 在类被载入时被显示初始化对于
  • I/O流读写文件详解

    文件类 文件中路径的写法 xff1a 1 String filePath 61 34 C AAA a txt 34 第一个 表示转义字符 2 filePath 61 34 C 34 43 File pathSeparator 43 34 A
  • 日志工具Log4J

    目前在java编程中 xff0c 日志已经发展出一套成熟的机制 常用的日志控件有Commons logging log4j以及JDK自带的Logging 从最初的System out println 到现在的Log4j xff0c java
  • CAS单点登录(七)——自定义验证码以及自定义错误信息

    在前面我们讲解了CAS单点登录 六 自定义登录界面和表单信息 xff0c 知道了如何去实现页面和表单信息的自定义信息提交 xff0c 就像我们提交表单的信息可能包括手机 邮箱等等 xff0c 这些都能以我们前面的知识点去解决 但平时登录我们
  • Http协议之Request和Response

    协议版本 xff1a Http 1 0 Http 1 1 http1 0协议中 xff0c 客户端与服务器建立连接后 xff0c 只能获得一个 web 资源 http1 1协议中 xff0c 客户端与服务器建立连接后 xff0c 在一个连接
  • Cookie详解

    介绍Cookie xff0c 我们先了解一下什么是会话 会话 xff1a 用户开一个浏览器用于查询相关信息 xff0c 点击多个超链接 xff0c 访问对应的多个web资源 xff08 需要查询的资源 xff09 xff0c 然后关闭浏览器
  • Session浅谈

    在web开发中 xff0c 服务器可以为每个用户浏览器创建一个会话对象 xff08 Session对象 xff09 xff0c 注意 xff0c 一个浏览器独占一个session对象 xff08 默认情况下 xff09 因此 xff0c 在