注:该系列所有测试均在之前创建的Shiro3的Web工程的基础上。

下面我们来说一下Shiro里面的会话管理,这个“会话”与JavaWeb里面的HttpSession

是一致的,都是表示客户端与服务器的一次会话。

Shiro会话概述

Shiro 提供了完整的企业级会话管理功能,不依赖于底层容 器(如web容器tomcat),不管 JavaSE 还是 JavaEE 环境 都可以使用,提供了会话管理、会话事件监听、会话存储/ 持久化、容器无关的集群、失效/过期支持、对Web 的透明 支持、SSO 单点登录的支持等特性。

会话相关的API


  1. Subject.getSession():​即可获取会话;其等价于 Subject.getSession(true),即如果当前没有创建 Session 对象会创建 一个;Subject.getSession(false),如果当前没有创建 Session 则返回 null 。
  2. session.getId():​获取当前会话的唯一标识 • session.getHost():获取当前Subject的主机地址。
  3. session.getTimeout() & session.setTimeout(毫秒):​获取/设置当 前Session的过期时间 。
  4. session.getStartTimestamp() & session.getLastAccessTime():​ 获取会话的启动时间及最后访问时间;如果是 JavaSE 应用需要自己定 期调用 session.touch() 去更新最后访问时间;如果是 Web 应用,每次进入 ShiroFilter 都会自动调用 session.touch() 来更新最后访问时间。
  5. session.touch() & session.stop():​更新会话最后访问时 间及销毁会话;当Subject.logout()时会自动调用 stop 方法 来销毁会话。如果在web中,调用 HttpSession. invalidate() 也会自动调用Shiro Session.stop 方法进行销毁Shiro 的会话 。
  6. session.setAttribute(key, val) & session.getAttribute(key) & session.removeAttribute(key):​设置/获取/删除会话属 性;在整个会话范围内都可以对这些属性进行操作。
  7. session.getHost()​:获取当前Subject的主机地址。
  8. SessionListener会话监听器用于监听会话创建、过期以及停止事件:​onStart(Session)、onStop(Session)、onExpiration(Session)分别监听了Session启动、销毁以及Session过期的时候。与HttpSessionListener很相似。

在Controller层,我们建议大家使用原生的HttpSession。那么Shiro的Session有什么意义呢?要知道,我们在传统的Web应用中,是无法在Service层获取Session会话的,也不建议这么做(应用会变成侵入式的)。但是现在有了Shrio的Session后,我们就可以在Service中使用会话。

下面我们测试一下,在之前的测试工程的ShiroLoginController中的为了测试权限注解的testShiroAnnocation方法参数中,添加传统会话HttpSession,并在Session中放置一个参数:

package com.test.shiro.controller;
import javax.servlet.http.HttpSession;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.test.shiro.services.ShiroService;

@Controller
@RequestMapping("userAuth")
public class ShiroLoginController {

@Autowired
private ShiroService shiroService;

@RequestMapping("/testShiroAnnocation")
private String testShiroAnnocation(HttpSession session){
session.setAttribute("test", "Hello1234");
shiroService.testMethod();
return "redirect:/list.jsp";
}
//下面的其它代码省略
}

然后在shiroService的testMethod方法中通过Shiro的Session获取我们在Controller中设置的参数:

Shiro会话管理_java

然后我们重启Web测试项目,使用admin登录后,在主页访问“/testShiroAnnocation”服务:

Shiro会话管理_apache_02

总结:

在Controller层我们使用的是HttpSession,而在Service层我们使用的是Shiro的Session,这样的话提供了一个好处,就是即便是在Service层,我们也可以访问到Session的数据。在开发中这个特性是很方便的,这也是Shiro的Session会话在开发中的一个重要作用。