编程示例: Session Id的生成

实现思路

Session的实现方式如下:在用户第一次登录的时候,系统为它分配一个唯一Id(被称为Session Id)作为标识,并且

记录下这个用户的用户名、要登录的账套名、用户拥有的权限等,以Id为键,用户名、账套名等信息为值保存到一

张Session哈希表中。以后客户端登录的时候只要提供此Id即可,应用服务器可以通过此Id到Session哈希表中查询

到所需要的一切信息。因为Session哈希表是保存在存储器中的(通常是内存),存储过多的Session信息将会占用内存

空间,所以客户端退出的时候要通知应用服务器注销此Id。

具体到细节还有一些问题需要处理:

l 如何生成唯一的Id。

l 如何保存用户名、账套名等信息,如何能在Session中放入自定义的信息。

l 如何维护管理Session。

l 如何清除Session。当系统非正常退出的时候,比如客户端机器故障,客户端是无法通知应用服务器注销Id的,

这会造成应用服务器中存在垃圾Session。

l 如何防止此Id被恶意程序截获,从而冒充合法客户端登录系统。

Session Id的生成

客户端Session Id的生成与数据库中的主键生成面对的问题是类似的。以可移植、高效率、可靠的方式来生成主键是一个非常重要的问题。可移植指的是主键生成策略不能依赖于服务器、操作系统、数据库等;高效率是生成主键的过程必须足够快,不能让生成主键的算法成为系统的瓶颈;可靠指的是生成的主键必须保证唯一性。主键生成方式可以分为数据库相关方式和数据库无关方式两种。

数据库相关方式是通过数据库的帮助来生成主键。对于支持自增字段的数据库,可以借助其序列号发生器来产生唯一的主键;对于不支持自增字段的数据库,可以在系统中放置一张表,采用此表记录本次生成的主键,这样就保证了生成的主键与以前的不冲突。数据库相关方式的优点是实现简单,而且可以完全保证生成主键的唯一性;不过由于需要数据库来维护主键的状态和同步对主键生成器的访问,所以对数据库有依赖性,而且由于需要访问数据库,其生成速度较慢。

数据无关方式是无须依靠数据库而生成主键的方式。最典型的算法就是UUID算法。UUID是一个字符串,它被编码为包含了使生成的UUID在整个空间和时间上都完全唯一的所必需的系统信息集,不管这个UUID是何时何地被生成的。原始的UUID规范是由Paul Leach和Rich Salz在网络工作组因特网草案中定义的。

UUID字符串一般由下面信息构成:

l 系统时钟的毫秒值。这是通过System.currentTimeMillis()方法得到的。这保证了在时间维度上产生主键的唯一性。

l 网络IP或者网卡标识。这保证了在集群环境中产生主键的唯一性。

l 精确到在一个JVM内部的对象的唯一。通常是System.identityHashCode(this)所调用产生的编码,这个方法调用保证对JVM中不同对象返回不同的整数。即使在同一台机器上存在多个JVM,两个UUID生成器返回相同的UUID的情况也极不可能发生。

l 在一个对象内的毫秒级的唯一。这是由与每一个方法调用所对应的随机整数,这个随机整数是通过使用java.security.SecureRandom类生成的。这可以保证在同一毫秒内对同一个方法的多个调用都是唯一的。

上述这些部分组合在一起,就可以保证生成的UUID在所有机器中(IP不重复或者网卡地址不重复),以及在同一台机器上的JVM内部的所有UUID生成器的实例中都保持唯一,并且能精确到毫秒级甚至是一个毫秒内的单个方法调用的级别。

流行的UUID算法有很多,这些算法有的不能完全保证生成的UUID的唯一性,必须根据情况选用。下面推荐两种UUID实现算法。

【例】UUID.Hex算法。

这个算法是Hibernate中主键策略为"uuid.hex"时所使用的算法,代码位于包org.hibernate.id下的UUIDHexGenerator.java文件中。

调用方法:

IdentifierGenerator gen = new UUIDHexGenerator();

for (int i = 0; i < 10; i++)

{

String id = (String) gen.generate(null, null);

System.out.println(id);

}

运行结果(UUID的生成是不重复的,每次的运行结果都会不同):

相关推荐
雨辰AI7 分钟前
openGauss 生产运维避坑指南|适配信创项目改造核心难点
java·运维·后端
名字还没想好☜24 分钟前
Java 21 switch 模式匹配实战:sealed 接口 + record 替代 if-instanceof 链
java·人工智能·后端·python·spring
devilnumber33 分钟前
Java 30 组高频技术 / 知识点多角度对比
java·开发语言
摇滚侠39 分钟前
《SpringBoot 3:入门与应用实战》第 6 章 Spring Boot 最佳实践 阅读笔记 10
java·spring boot·笔记
gugucoding1 小时前
57. 【Java】日志框架:SLF4J与Logback
java·开发语言·logback
今天的砖头有点烫手啊1 小时前
JVM 调优实战:从 GC 日志到参数优化,一次完整排查
java·jvm
爱奥尼欧1 小时前
10.C++ string 实现详解
java·开发语言·c++
小飞学编程...1 小时前
【equals 、Comparable、Comparator 三者的区别】
java·python
骇客野人1 小时前
Java分布式任务调度方案(完整落地指南)
java·开发语言·分布式
JacksonMx2 小时前
Spring @Async 坑点 + 改造方案
java·开发语言