会话技术之 Session

不多废话,先来一个 HelloWorld。

Session 有 get 肯定要先有 set 。

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码
resp.setContentType("text/html;charset=UTF-8");
// get 到session
HttpSession session = req.getSession();
//有中文,别忘了编码再传进去
session.setAttribute("HelloWorld", URLEncoder.encode("Hello--World!向世界宣告我的到来!","UTF-8"));
}

这里分两个Servlet编写

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码
resp.setContentType("text/html;charset=UTF-8");
// get 到 session
HttpSession session = req.getSession();
// 获取到值,别忘了解码
String helloWorld = URLDecoder.decode((String) session.getAttribute("HelloWorld"),"UTF-8");
//输出一下
resp.getWriter().write(helloWorld);
}

Session API

  • long getCreationTime();【获取Session被创建时间】
  • String getId();【获取Session的id】
  • long getLastAccessedTime();【返回Session上一次访问的时间】
  • ServletContext getServletContext();【获取ServletContext对象】
  • void setMaxInactiveInterval(int var1);【设置Session超时时间】
  • int getMaxInactiveInterval();【获取Session超时时间】
  • Object getAttribute(String var1);【获取Session属性】
  • Enumeration getAttributeNames();【获取Session所有的属性名】
  • void setAttribute(String var1, Object var2);【设置Session属性】
  • void removeAttribute(String var1);【移除Session属性,注意==不是销毁该Session
  • void invalidate();【销毁该Session】
  • boolean isNew();【该Session是否为新的】

还有些过时的方法就不一一列举了

Session 有效期

在此之前先说一下 Session 的对象,是一个域对象, 只要Session 还没有被销毁(或者浏览器没有关闭),Servlet 就可以通过 Session 对象进行数据传递。

Session 的生命周期可以通过方法去控制的,直接杀死销毁掉,当然关闭浏览器也是可以直接杀死掉的。

//销毁该 session
session.invalidate();

还有可以通过时间的预先设置,在此时间段内目标Session 没有被访问,就会进行销毁。这是服务器出于防止内存溢出的考虑,将最久未访问的销毁。不知你是否嗅到了 least recently used (LRU)算法的味道。

这种方式又有三种途径可以去实现,同时作用范围也不尽相同。

在 Tomcat 的 web.xml 配置文件中配置(对部署在该服务器上的应用有效

可以看到默认的配置:

以分钟为单位,默认是 30 分钟。

接下来照葫芦画瓢,修改为 20 分钟:

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

保存即可生效,再次强调作用域,是部署在该 Tomcat 服务器上的所有项目。如果只是为了练手,验证结果后,别忘了修改回来,或者记住你曾经修改过。

在工程的 web.xml 文件中配置(对 web.xml 文件下的 web 应用有效

配置内容是一样滴。

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

这里提一个醒,web.xml 在 Servlet 2.3 中,配置的元素必须按照顺序配置。而Servlet 2.4 中是不需要的。那么如何知道自己用的是哪个版本呢?

很简单,你先不按顺序配,如下图所示报红了,那就说明你是 2.3 ,得乖乖按顺序配,提示也会贴心提醒你配置顺序。

在单个Servlet 中通过 setMaxInactiveInterval(int var1) 方法设置 (对单个 Session 有效

既然知道配置方法,那就来看看源码:

从源码可知,是以秒为单位配置的。我们还是来个 20 分钟。

//配置有效期
session.setMaxInactiveInterval(60*20);

既然三个作用范围,那就会有优先级的问题,这里由小见大,优先级为 3 > 2 > 1

Session 原理

依赖 Cookie

http://127.0.0.1:8080/ling/session/putSession 首先由访问地址来看,可知使用的是 Http 协议。Http 协议是一种无状态协议。服务器端并不能通过 Http 协议感知到浏览器中的是哪一个用户。

在浏览器中我们可以看到访问时,会为我们存下名为 JSESSIONID 的 Cookie ,它的值就是 Session的 ID。根本上,浏览器就是根据这一 Cookie 的值来判断是否是否为同一用户,该用哪一个 Session 进行通讯。注意他的生命周期,为 Session 。正合 Session 意。

删除此 Cookie 后,访问一个从 Session中取值的 Servlet ,会报空指针错误,如上所述,因为服务器是根据浏览器发送来名为 JSESSIONID 的 Cookie 来判断使用哪一个 Session,没有 Cookie 提供的 ID ,也就无从去找对应的 Session 了,自然会是服务器端报空指针的错。


那么问题来了,我禁用了 Cookie 的话,那 Session 不就不能用了吗?

是的,正常渠道下是不能用了。

URL 地址重写

注意这两种方法都需要禁用Cookie

关于对目标web 应用禁用 Cookie方法如下:

Java Web规范⽀持通过配置禁⽤Cookie,禁⽤⾃⼰项⽬的Cookie,在META-INF⽂件夹下的context.xml⽂件中修改(没有则创建),并编写如下内容:

<?xml version='1.0' encoding='utf-8'?>
<Context path="/ouzicheng" cookies="false">
</Context>

这里有由HttpServletResponse 提供两种方法进行 URL 地址重写:

  • encodeURL(String url) ;

看源码,我们再决定如何使用它:

这里需要注意源码中也说了,如果浏览器支持 Cookie,或者Session 被关闭(通常是Session是否执行了 invalidate() 方法),这时候是不会进行地址重写的。注意,该方法不能在不支持Cookie的浏览器中生效。

	// 目标url
String url = "/ling/session/testSession";
// 重写url,并重定向到目标url
resp.sendRedirect(resp.encodeURL(url));
  • encodeRedirectURL(String url);

源码里,坑爹的来了:

大概就是,有不同,你们用的时候小心,但是什么不同我就不具体说了。。。这就一个接口,我哪找源码去.....

		// 目标url
String url = "/ling/session/testSession";
// 重写url,并重定向到目标url
resp.sendRedirect(resp.encodeRedirectURL(url));

以上写法下,至少同一站点下,两者的效果并无差别:

要问有什么不同,源码上也看不出来什么。关于不同点,只在网络找到以下说法:

--------来自CSDN 。原文链接 :https://blog.csdn.net/SpbDev/article/details/37879549

encodeURL在附加jsessionid之前还对url做了判断处理:如果url为空字符串(长度为0的字符串),则将url转换为完整的URL(http或https开头的);如果url是完整的URL,但不含任何路径(即只包含协议、主机名、端口,例如http://127.0.0.1),则在末尾加上根路径符号/。

也就是encodeURL如果进行了编码,则返回的URL一定是完整URL而不是相对路径;而encodeRedirectURL则不对URL本身进行处理,只专注于添加jsessionid参数(如果需要)。

--------来自 STACK OVERFLOW 。问答链接:https://stackoverflow.com/questions/4944778/whats-the-difference-between-encodeurl-and-encoderedirecturl

The main difference between two is, the implementation of encodeRedirectURL method includes the logic to determine whether the session ID needs to be encoded in the URL in the case when you are redirecting the URL to different context where the session information is not required or invalid. The encodeURL method do not appent the seesion id if the cookies are enabled. In addition to this encodeRedirectURL do not append the session information if the URL is redirected to the different context (web application). Because the rules for making this determination can differ from those used to decide whether to encode a normal link, this method is separete from the encodeURL method.

主要是这句 “如果 URL 重定向到不同的上下文(Web 应用程序),encodeRedirectURL 不追加会话信息。”,然而无从验证,笔者通过两种方法,得到的是同一个 Session 的 ID 值。

.

会话技术之 Session的更多相关文章

  1. php会话技术之Session用法

    php会话技术之Session用法举例. 本文原始链接:http://www.jbxue.com/article/8940.html1.创建session <?php     //创建sessi ...

  2. [转]【会话技术】Session技术

    创建时间:6.29 & 6.30 一.Session技术 Session技术是将数据存储在服务器端的技术,会为每个客户端都创建一块内存空间  存储客户的数据,但客户端需要每次都携带一个标识ID ...

  3. Web核心之会话技术Cookie&Session

    什么是会话技术? http协议是无状态协议.为了满足在多次请求之间数据进行交互,推出了会话技术. 会话概念:一次会话,指的是从客户端和服务器建立起连接开始,到客户端或服务器断开连接为止.中间可能进行多 ...

  4. 会话技术之Session(购物车加入、查看和清空)

    会话技术之Session session:服务器端会话技术 当我们第一次访问的服务器的时候,服务器获取id, 能获取id 要拿着这个id去服务器中查找有无此session 若查找到了:直接拿过来将数据 ...

  5. java ->会话技术Cookie&Session

    会话技术Cookie&Session 会话技术简介 存储客户端的状态 由一个问题引出今天的内容,例如网站的购物系统,用户将购买的商品信息存储到哪里?因为Http协议是无状态的,也就是说每个客户 ...

  6. JavaWeb-10(会话技术之session&amp;JSP)

    JavaWeb-会话技术之session&JSP 会话管理之Session技术 一.Session 在WEB开发中,server能够为每一个用户浏览器创建一个会话对象(session对象),注 ...

  7. JavaWeb学习笔记五 会话技术Cookie&Session

    什么是会话技术? 例如网站的购物系统,用户将购买的商品信息存储到哪里?因为Http协议是无状态的,也就是说每个客户访问服务器端资源时,服务器并不知道该客户端是谁,所以需要会话技术识别客户端的状态.会话 ...

  8. JavaEE之会话技术Cookie&Session

    会话技术简介 存储客户端的状态 由一个问题引出今天的内容,例如网站的购物系统,用户将购买的商品信息存储到哪         里?因为Http协议是无状态的,也就是说每个客户访问服务器端资源时,服务器并 ...

  9. 会话技术Cookie&Session

    1.会话技术概述 从打开浏览器访问某个站点,到关闭这个浏览器的整个过程,称为一次会话.会话技术用于记录本次会话中客户端的状态与数据. 会话技术分为Cookie和Session: Cookie:数据存储 ...

随机推荐

  1. docker找回构建时被删除的文件

    设想这样一个场景:当一个docker镜像被多次引用构建,在某次构建中某个文件被删除,如何找回被删除的文件? 要想回答这么一个问题,首先得熟悉下docker镜像的分层存储结构,镜像每一层都是只读的: 那 ...

  2. Spring quartz中取得ServletContext

    在开发javaWeb定时任务的时候,有些处理要取得应用的相对路径,这就需要用到ServletContext取得到这个路径 解决思路是在web应用启动时,把ServletContext提前注入到Sche ...

  3. C#LeetCode刷题之#532-数组中的K-diff数对(K-diff Pairs in an Array)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3716 访问. 给定一个整数数组和一个整数 k, 你需要在数组里找 ...

  4. Linux学习日志——基本指令②

    文章目录 Linux学习日志--基本指令② 前言 touch cp (copy) mv (move) rm vim 输出重定向(> 或 >>) cat df(disk free) f ...

  5. HBase存储及读写原理介绍

    一.HBase介绍及其特点 HBase是一个开源的非关系型分布式数据库,它参考了谷歌的BigTable建模,实现的编程语言为Java.它是Apache软件基金会的Hadoop项目的一部分,运行于HDF ...

  6. peewee的简单使用

    peewee的简单使用 peewee是一个轻量级的ORM框架,peewee完全可以应对个人或企业的中小型项目的Model层,上手容易,功能强大. 一.安装peewee模块 使用pip命令工具安装pee ...

  7. put数据到topic

    基于python3.6 # -*-coding:utf-8 *- __author__ = 'lc_yy' from pykafka import KafkaClient import logging ...

  8. 用mysqldump备份数据库

    格式:/usr/local/mysql/bin/mysqldump -hip -Pport -uuser -ppasswd --set-gtid-purged=off  --database aa & ...

  9. 分析dubbo心跳检测机制

    目的: 维持provider和consumer之间的长连接 实现: dubbo心跳时间heartbeat默认是60s,超过heartbeat时间没有收到消息,就发送心跳消息(provider,cons ...

  10. java基础-03:注释

    1.注释的意义: (1) 为了更好的阅读自己编写的代码,方便日后代码维护,建议添加注释. (2) 有利于团队协作. (3) 代码即文档.程序源代码是程序文档的重要组成部分. 2.注释分类 (1) 单行 ...