Springboot整合(10)——Intercepter
Springboot整合(10)——Intercepter
本节说明2种拦截器的应用场景:为Shiro RememberMe功能提供session初始化和记录系统日志
为Shiro RememberMe功能提供session初始化
上一节讲述了shiro的配置,在最后的部分配置了shiro的rememberMe功能,但实际上遗留了一个小问题:登陆的时候我们知道,shiro会调用MyShiroRealm的doGetAuthenticationInfo方法,回头去看这个方法,你会发现session初始化是在这个方法里做的。而我们一旦使用了rememberMe功能,这个方法是不会调的,那么问题就来了,session无法初始化。如何解决这个问题呢?其中一种做法就是使用intercepter,具体做法如下:
1. 编写SessionIntercepter
@Component
publicclass SessionInterceptor implements HandlerInterceptor {
privatefinal Log LOG = LogFactory.getLog(SessionInterceptor.class);
@Resource
private UserService userInfoService;
@Override
publicboolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
LOG.info("---preHandle---");
System.out.println(request.getContextPath());
Subject currentUser = SecurityUtils.getSubject();
// 判断用户是通过记住我功能自动登录,此时session失效
if (!currentUser.isAuthenticated() && currentUser.isRemembered()) {
Session session = currentUser.getSession();
SysUser userInfo = (SysUser) currentUser.getPrincipal();
session.setAttribute("userId", userInfo.getId());
session.setAttribute("user", userInfo);
}
returntrue;
}
@Override
publicvoid postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
ModelAndView modelAndView) throws Exception {
LOG.info("---postHandle---");
}
@Override
publicvoid afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
Object o, Exception e) throws Exception {
LOG.info("---afterCompletion---");
}
}
2. 在MyWebAppConfigurer中配置SessionIntersepter
@Resource
private SessionInterceptor sessionInterceptor;
/**
* 拦截器
*
*/
@Override
publicvoid addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(sessionInterceptor).addPathPatterns("/**").excludePathPatterns("/user/login");
super.addInterceptors(registry);
}
3. 在Controller中访问session。随便找个controller访问session,就用indexController吧。顺便说一下shiro里的session要怎么用:
Subject currentUser = SecurityUtils.getSubject();
Session session = currentUser.getSession();
System.out.println(session.getAttribute("user"));
4. 测试
可以尝试先不加入SessionIntercepter,即把下面这行代码注释掉
// registry.addInterceptor(sessionInterceptor).addPathPatterns("/**").excludePathPatterns("/user/login");
此时测试会发现后台打印的session值为null
加入SessionIntercepter,再测session值正常打印
记录系统日志
记录系统日志的意义就不多赘述了,直接说实现
1. 编写LogIntercepter
@Component
publicclass LogInterceptor implements HandlerInterceptor {
@Override
publicboolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
returntrue;
}
@Override
publicvoid postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
publicvoid afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// 保存日志到数据库的逻辑,根据实际情况自行实现
// LogService.saveLog(request, handler, ex, null);
System.out.println("HOST : " + request.getRemoteHost());
System.out.println("URI : " + request.getRequestURI());
System.out.println("ParamMap : " + request.getParameterMap());
}
}
2. 在MyWebAppConfigurer中配置LogIntersepter
@Resource
private LogInterceptor logInterceptor;
registry.addInterceptor(logInterceptor).addPathPatterns("/**");
3. 测试,启动项目,访问任意url,后台都会打印LogIntercepter中设置的信息