编程示例: 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的生成是不重复的,每次的运行结果都会不同):

相关推荐
怒放吧德德7 小时前
Netty 4.2 入门指南:从概念到第一个程序
java·后端·netty
雨中飘荡的记忆8 小时前
大流量下库存扣减的数据库瓶颈:Redis分片缓存解决方案
java·redis·后端
心之语歌11 小时前
基于注解+拦截器的API动态路由实现方案
java·后端
华仔啊12 小时前
Stream 代码越写越难看?JDFrame 让 Java 逻辑回归优雅
java·后端
ray_liang12 小时前
用六边形架构与整洁架构对比是伪命题?
java·架构
Ray Liang13 小时前
用六边形架构与整洁架构对比是伪命题?
java·python·c#·架构设计
Java水解14 小时前
Java 中间件:Dubbo 服务降级(Mock 机制)
java·后端
SimonKing18 小时前
OpenCode AI辅助编程,不一样的编程思路,不写一行代码
java·后端·程序员
FastBean18 小时前
Jackson View Extension Spring Boot Starter
java·后端
Seven9719 小时前
剑指offer-79、最⻓不含重复字符的⼦字符串
java