干货,一文带你超详细了解Session的原理及应用

时间:2021-12-21 00:19:55

session 简介

session 是我们 jsp 九大隐含对象的一个对象。

session 称作域对象,他的作用是保存一些信息,而 session 这个域对象是一次会话期间使用同一个对象。所以这个对象可以用来保存共享数据。

  • 使用 Cookie 有一个非常大的局限,就是如果 Cookie 很多,则无形的增加了客户端与服务端的数据传输量。而且由于浏览器对 Cookie 数量的限制,注定我们不能再 Cookie 中保存过多的信息,于是 Session 出现。
  • Session 的作用就是在服务器端保存一些用户的数据,然后传递给用户一个名字为JSESSIONID 的 Cookie,这个 JESSIONID 对应这个服务器中的一个 Session 对象,通过它就可以获取到保存用户信息的 Session。

session 是基于 cookie 的。

在用户第一次使用 session 的时候(访问 jsp 页面会获取 session,所以一般访问 index.jsp 就算是第一次使用 session 了),服务器会为用户创建一个 session 域对象。使用 jsessionid 和这个对象关联,这个对象在整个用户会话期间使用。响应体增加 set-cookie:jsessionid=xxx 的项。用户下次以后的请求都会携带 jsessionid 这个参数,我们使用 request.getSession()的时候,就会使用 jsessionid 取出 session 对象。

session 原理图:

干货,一文带你超详细了解Session的原理及应用

HttpSession 的生命周期

什么时候创建 HttpSession 对象

①. 对于 JSP: 是否浏览器访问服务端的任何一个 JSP, 服务器都会立即创建一个 HttpSession 对象呢?
不一定。

  • 若当前的 JSP 是客户端访问的当前 WEB 应用的第一个资源,且 JSP 的 page 指定的 session 属性值为 false,则服务器就不会为 JSP 创建一个 HttpSession 对象;
  • 若当前 JSP 不是客户端访问的当前 WEB 应用的第一个资源,且其他页面已经创建一个 HttpSession 对象,则服务器也不会为当前 JSP 页面创建一个 HttpSession 对象,而会把和当前会话关联的那个 HttpSession 对象返回给当前的 JSP 页面.

②. 对于 Serlvet: 若 Serlvet 是客户端访问的第一个 WEB 应用的资源,则只有调用了 request.getSession() 或 request.getSession(true) 才会创建 HttpSession 对象

page 指令的 session=“false“ 表示什么意思?

当前 JSP 页面禁用 session 隐含变量!但可以使用其他的显式的 HttpSession 对象

在 Serlvet 中如何获取 HttpSession 对象?

request.getSession(boolean create): 

create 为 false, 若没有和当前 JSP 页面关联的 HttpSession 对象, 则返回 null; 若有, 则返回 true
create 为 true, 一定返回一个 HttpSession 对象. 若没有和当前 JSP 页面关联的 HttpSession 对象, 则服务器创建一个新的HttpSession 对象返回, 若有, 直接返回关联的. 
request.getSession(): 等同于 request.getSession(true)

什么时候销毁 HttpSession 对象

①. 直接调用 HttpSession 的 invalidate() 方法: 该方法使 HttpSession 失效

②. 服务器卸载了当前 WEB 应用.

③. 超出 HttpSession 的过期时间.

④. 并不是关闭了浏览器就销毁了 HttpSession.

session 使用

获取 session 对象

HttpSession session = request.getSession();

session 是我们的四大域对象之一。用来保存数据。常用的方法

session.setAttribute("user", new Object()); session.getAttribute("user");
session.setMaxInactiveInterval(**);//秒为单位
session.invalidate();//使 session 不可用

Session 时 效

①、基本原则

Session 对象在服务器端不能长期保存,它是有时间限制的,超过一定时间没有被访问过的 Session 对象就应该释放掉,以节约内存。所以 Session 的有效时间并不是从创建对象开始计时,到指定时间后释放——而是从最后一次被访问开始计时,统计其“空闲” 的时间。

②、默认设置

在全局 web.xml 中能够找到如下配置:

<session-config>
<session-timeout></session-timeout>
</session-config>

③、手工设置

session.setMaxInactiveInterval(int seconds) 
session.getMaxInactiveInterval()

④、强制失效

session.invalidate()

⑤、可以使 Session 对象释放的情况

Session 对象空闲时间达到了目标设置的最大值,自动释放

Session 对象被强制失效

Web 应用卸载服务器进程停止

URL 重写

在整个会话控制技术体系中,保持 JSESSIONID 的值主要通过 Cookie 实现。但 Cookie 在浏览器端可能会被禁用,所以我们还需要一些备用的技术手段,例如:URL 重写。

1)URL 重写其实就是将 JSESSIONID 的值以固定格式附着在 URL 地址后面,以实现保持

JSESSIONID,进而保持会话状态。这个固定格式是:URL;jsessionid=xxxxxxxxx

例如:

targetServlet;jsessionid=F9C893D3E77E3E8329FF6BD9B7A09957

2) 实 现 方 式 :

response.encodeURL(String)
response.encodeRedirectURL(String)

例如:

//1.获取Session对象
HttpSession session = request.getSession(); //2.创建目标URL地址字符串
String url = "targetServlet"; //3.在目标URL地址字符串后面附加JSESSIONID的值
url = response.encodeURL(url); //4.重定向到目标资源
response.sendRedirect(url);

Session 的活化和钝化

Session 机制很好的解决了 Cookie 的不足,但是当访问应用的用户很多时,服务器上就会创建非常多的 Session 对象,如果不对这些 Session 对象进行处理,那么在 Session 失效之前,这些 Session 一直都会在服务器的内存中存在。那么就,就出现了 Session 活化和钝化的机制。

1)Session 钝化:

Session 在一段时间内没有被使用时,会将当前存在的 Session 对象序列化到磁盘上,而不 再 占 用 内 存 空 间 。

2)Session 活化:

Session 被钝化后,服务器再次调用 Session 对象时,将 Session 对象由磁盘中加载到内存中使用。

如果希望 Session 域中的对象也能够随 Session 钝化过程一起序列化到磁盘上,则对象的实现类也必须实现 java.io.Serializable 接口。不仅如此,如果对象中还包含其他对象的引用,则被关联的对象也必须支持序列化,否则会抛出异常:java.io.NotSerializableException

表单重复提交问题

什么是表单重复提交?

同一个表单中的数据内容多次提交到服务器。 危害:

服务器重复处理信息,负担加重。

如果是保存数据可能导致保存多份相同数据。

几种重复提交

1)提交完表单后,直接刷新页面,会再次提交。

- 根本原因:Servlet 处理完请求以后,直接转发到目标页面。

- 这样整一个业务,只发送了一次请求,那么当你在浏览器中点击刷新按钮或者狂按 f5,会一直都会刷新之前的请求

解决方案:使用重定向跳转到目标页面

2)提交表单后,由于网速差等原因,服务器还未返回结果,连续点击提交按钮,会重  复提交。

- 根本原因:按钮可以多次点击

- 解决方案:通过 js,使得按钮只能提交一次。

$(“#form1”).submit(function(){
$(“#sub_btn”).prop(“disabled”,true);
})

3)表单提交后,点击浏览器回退按钮,不刷新页面,点击提交按钮再次提交表单

- 根本原因:服务器并不能识别请求是否重复。

- 解决方案:使用 token 机制。

1、页面生成时,产生一个唯一的 token 值。将此值放入 session

2、表单提交时,带上这个 token 值。

3、服务端验证 token 值存在,则提交表单,然后移除此值。验证 token 不存在,说明是之前验证过一次被移除了,所以是重复请求。不予处理

原理:

干货,一文带你超详细了解Session的原理及应用

代码:

jsp 页面

<%
  String token = System.currentTimeMillis() + "";
  request.getSession().setAttribute(token, "");
%>
<div>
  <h1>测试表单重复提交</h1>
  <form action="login" method="get">
    用户名:<input name="username" type="text"/>
    密码:<input name="password" type="password">
    <input name="token" value="<%=token%>">
    <input type="submit">
  </form>
  <hr>
</div>

Servlet

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String token = request.getParameter("token");
Object attribute = session.getAttribute(token);
response.setContentType("text/html;charset=UTF-8");
if(attribute!=null){
session.removeAttribute(token);
response.getWriter().write("请求成功!");
}else{
response.getWriter().write("请不要重复请求!");
}
}

其实防止重复提交的核心就是让服务器有一个字段能来识别此次请求是否已经执行。 这个字段需要页面传递过来,因为只要回退回去的页面,字段都是一致的。不会变化, 通过这个特性我们想到了 token 机制来防止重复提交

干货,一文带你超详细了解Session的原理及应用的更多相关文章

  1. 干货,一文带你超详细了解 Filter 的原理及应用

    提出问题 1.我们在访问后台很多页面时都需要登录,只有登录的用户才能查看这些页面,我们需要   在每次请求的时候都检查用户是否登陆,这样做很麻烦,有没有一种方法可以在我们请求之   前就帮我们做这些事 ...

  2. 一文带你超详细了解Cookie

    cookie 简介 什么是 cookie cookie,有时我们也用其复数形式 cookies,是服务端保存在浏览器端的数据片段.以 key/value的形式进行保存.每次请求的时候,请求头会自动包含 ...

  3. js的dom对象(带实例超详细全解)

    js的dom对象(带实例超详细全解) 一.总结 一句话总结: 1.DOM中的方法区分大小写么? 解答:区分 2.DOM中元素和节点的关系式什么? 解答:元素就是标签,节点中有元素节点,也是标签,节点中 ...

  4. 【Python扩展阅读【转】EasyGui 学习文档【超详细中文版】】

    翻译改编自官方文档:http://easygui.sourceforge.net/tutorial/index.html 翻译改编者:小甲鱼,本文欢迎转载,转载请保证原文的完整性! 演示使用 Pyth ...

  5. EasyGui 学习文档【超详细中文版】

    演示使用 Python 3.3.3 版本 0. 安装 EasyGui 官网:http://easygui.sourceforge.net 最新版: <ignore_js_op> easyg ...

  6. mac自带功能超详细介绍

    mac自带的超实用的功能分享给大家,包含自带的Spotlight(聚焦) 计算器功能,预览的 PDF 压缩功能,切换同一应用的不同窗口等,让您的工作更加轻松. 1.Spotlight(聚焦) 计算器功 ...

  7. 如何在idea中将项目生成API文档(超详细)(Day&lowbar;32)

    1.打开要生成API文档的项目,点击菜单栏中的Tools工具,选择Generate JavaDoc 2.打开如下所示的Specify Generate JavaDoc Scope 界面 3.解释下Ot ...

  8. 一文读懂&colon;超详细正态分布方差等于o的推导

    (uv)' = [(u+△u)(v+△v) - uv] /△x = (v△u+u△v +△u△v)/△x = v(△u/△x) + u(△v/△x) +(△u△v)/△x =u'v+uv'

  9. 转帖&colon; 一份超全超详细的 ADB 用法大全

    增加一句 连接 网易mumu模拟器的方法 adb  connect 127.0.0.1:7555 一份超全超详细的 ADB 用法大全 2016年08月28日 10:49:41 阅读数:35890 原文 ...

随机推荐

  1. Hibernate全套增删改查&plus;分页

    1.创建一个web工程 2.导入jar包 3.创建Student表 4.创建实体类 package com.entity; public class Student { private Integer ...

  2. ionic 开发笔记

    1.AngularJS 外部的控制器(DOM 事件.外部的回调函数如 jQuery UI 空间等)调用了 AngularJS 函数之后,必须调用$apply.在这种情况下,你需要命令 AngularJ ...

  3. Java分布式Socket监控项目思考

    内容说明 一项课程作业Java编写Socket长连接监控分布式终端,并将终端状态写入数据库供前端查询 基础:c++/Posix/APUE/Mysql&sqlite 核心内容:Socket/线程 ...

  4. Javascript获取URL地址变量参数值的方法

    今天碰到在做一个动态页面的时候,需要用到 URL 的参数值来作判断,从而决定某一块内容在当前页面是否显示.例如exampe.html?parm1=xxx&parm2=xxx&parm3 ...

  5. sql之事务和并发

    1.Transaction(事务)是什么: 事务是作为单一工作单元而执行的一系列操作.包括增删查改. 2.事务的种类: 事务分为显示事务和隐式事务: 隐式事务:就是平常我们使用每一条sql 语句就是一 ...

  6. PHP编译安装出错configure&colon; error&colon; mcrypt&period;h not found&period; Please reinstall libmcrypt的解决办法

    1.下载libmcrypt wget http://jaist.dl.sourceforge.net/project/mcrypt/Libmcrypt/2.5.8/libmcrypt-2.5.8.ta ...

  7. 自己写RTPserver——大约RTP协议

    自己写RTPserver--大约RTP协议 本文将带领你一步一步地实现一个简单的手RTP变速器server,旨在了解RTP流媒体传输协议以及有关多媒体编解码器的一些知识. RTP协议的必备知识 要动手 ...

  8. Net 自定义Excel模板导出数据

    转载自:http://www.cnblogs.com/jbps/p/3549671.html?utm_source=tuicool&utm_medium=referral 1 using Sy ...

  9. Java网络连接之HttpURLConnection、HttpsURLConnection

    工具类包含两个方法: http请求.https请求 直接看代码: package com.jtools; import java.io.BufferedReader; import java.io.I ...

  10. Windows下搭建Git服务器各种问题汇总(一)

    **************************************************************************************************** ...