Spring + Shiro 项目 + HttpSessionListener 【调用springService问题】&【Session失效问题】
功能描述:
当用户退出(主动)或者关闭浏览器(session超时)的时候,利用本次登录Ip更新上次登录IP。有人可能要问,你在用户登录的时候记录不就行了。可是我有两个字段,一个为本次登录IP,另外一个为上次登录IP。当用户退出的时候,本次登录IP也就成了上次登录IP。
首先解决的问题是:在Listener里面访问Service。
因为是基于注解开发,将Listener扫描和将Service成员变量注解@Autowired是不能解决问题的。运行起来会报空指针。
public class UserLeaveListener implements HttpSessionListener {
private UserService userService;
@Override
public void sessionCreated(HttpSessionEvent arg0) {
// 记录访问日志:IP
}
@Override
public void sessionDestroyed(HttpSessionEvent arg0) {
System.out.println("---SessionListener---");
//调用 session.invalidate(); 后,在这个方法里仍然可以获取到属性值
ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(
arg0.getSession().getServletContext());
userService = applicationContext.getBean(UserService.class);
HttpSession session = arg0.getSession();
User user = (User) session.getAttribute("user");
System.out.println("user:" + user);
//如果user不为空,代表超时退出。否则是主动退出
if(user != null){
System.out.println("用户超时退出:" + user.getUserName());
userService.updatePreIp(user.getUserId(), user.getUserCurIP());
}else{
System.out.println("用户已经退出");
}
}
}
核心代码便是
ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(
arg0.getSession().getServletContext());
userService = applicationContext.getBean(UserService.class);
第二个问题:在我的登出Controller方法中,我调用
session.invalidate();
后的确能够进入listener,也成功执行了service方法,但是却爆了错。这个错不影响什么,但是看起来难受
严重: Servlet.service() for servlet [springDispatcherServlet] in context with path [/target] threw exception [org.apache.shiro.session.InvalidSessionException: java.lang.IllegalStateException: getAttribute: Session already invalidated] with root cause
java.lang.IllegalStateException: getAttribute: Session already invalidated
at org.apache.catalina.session.StandardSession.getAttribute(StandardSession.java:1190)
at org.apache.catalina.session.StandardSessionFacade.getAttribute(StandardSessionFacade.java:103)
at org.apache.shiro.web.session.HttpServletSession.getAttribute(HttpServletSession.java:146)
at org.apache.shiro.session.ProxiedSession.getAttribute(ProxiedSession.java:121)
at org.apache.shiro.subject.support.DelegatingSubject.getRunAsPrincipalsStack(DelegatingSubject.java:469)
at org.apache.shiro.subject.support.DelegatingSubject.getPrincipals(DelegatingSubject.java:153)
at org.apache.shiro.subject.support.DelegatingSubject.getPrincipal(DelegatingSubject.java:149)
at org.apache.shiro.web.servlet.ShiroHttpServletRequest.getSubjectPrincipal(ShiroHttpServletRequest.java:96)
at org.apache.shiro.web.servlet.ShiroHttpServletRequest.getUserPrincipal(ShiroHttpServletRequest.java:112)
at org.springframework.web.servlet.FrameworkServlet.getUsernameForRequest(FrameworkServlet.java:1091)
at org.springframework.web.servlet.FrameworkServlet.publishRequestHandledEvent(FrameworkServlet.java:1077)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1502)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1458)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
看这句:
[org.apache.shiro.session.InvalidSessionException: java.lang.IllegalStateException: getAttribute: Session already invalidated]
可以知道这个shiro啊,他想找这个session玩,但是session已经不在了。经过查阅我猜整合了shiro之后,就得考虑shiro的感受了。那么shiro有没有退出的方法呢?
SecurityUtils.getSubject().logout();
原来有啊,我就在controller方法中把它也加上了。
运行成功之后,又报错了。
java.lang.IllegalStateException: invalidate: Session already invalidated
我很怀疑用了shiro之后,shiro就霸占了session。所以我就把session.invalidate去掉了
果然运行之后啥错误都没有了。
客户端地址:0:0:0:0:0:0:0:1
user:User [userId=14962441362734L7V7MF, userName=博美, ...]
用户主动退出:博美
---SessionListener---
user:User [userId=14962441362734L7V7MF, userName=博美, ...]
用户超时退出:博美
---SessionListener---
user:null
用户已经退出
这里说一下,虽然我们调用了让session失效的方法,但是等到session超时时间一到,会再次进入sessionListener中
Spring + Shiro 项目 + HttpSessionListener 【调用springService问题】&【Session失效问题】的更多相关文章
- spring boot项目启动报(No session repository could be auto-configured, check your configuration (session store type is 'null'))
找到项目的application配置文件,增加 spring.session.store-type=none,重新启动问题解决 注:因为项目未使用redis管理session,可以如上设置,如果想使用 ...
- 解决ajax 遇到session失效后自动跳转的问题
在项目中,经常会遇到session失效后,点击任何链接无反应的情况!这样给客户的体验就不是很好,以为是系统出了故障!所以在项目中我们会处理session失效后的跳转问题(一般给用户提示,并跳转后登录页 ...
- Spring Cloud项目中通过Feign进行内部服务调用发生401\407错误无返回信息的问题
问题描述 最近在使用Spring Cloud改造现有服务的工作中,在内部服务的调用方式上选择了Feign组件,由于服务与服务之间有权限控制,发现通过Feign来进行调用时如果发生了401.407错误时 ...
- 控制反转和spring在项目中可以带来的好处
Spring实例化Bean的三种方式分别是: 1,xml配置使用bean的类构造器 <bean id="personService" class="cn.servi ...
- Spring顶级项目以及Spring cloud组件
作为java的屌丝,基本上跟上spring屌丝的步伐,也就跟上了主流技术. spring 顶级项目: Spring IO platform:用于系统部署,是可集成的,构建现代化应用的版本平台,具体来说 ...
- Java Spring MVC项目搭建(二)——项目配置
1.站点配置文件web.xml 每一个Spring MVC 项目都必须有一个站点配置文件web.xml,他的主要功能吗....有一位大哥已经整理的很好,我借来了,大家看看: 引用博客地址: http: ...
- Spring Boot实战笔记(二)-- Spring常用配置(Scope、Spring EL和资源调用)
一.Bean的Scope Scope描述的是Spring容器如何新建Bean实例的.Spring的Scope有以下几种,通过@Scope注解来实现. (1)Singleton:一个Spring容器中只 ...
- Shiro+Redis实现tomcat集群session共享
一.背景 当我们使用了nginx做项目集群以后,就会出现一个很严重的问题亟待解决,那就是:tomcat集群之间如何实现session共享的问题,如果这个问题不解决,就会出现登陆过后再次请求资源依旧 ...
- spring shiro 集成
1.向spring项目中添加shiro相关的依赖 <dependency> <groupId>commons-logging</groupId> <artif ...
随机推荐
- nginx应用总结(1)-- 基础知识和应用配置梳理
在linux系统下使用nginx作为web应用服务,用来提升网站访问速度的经验已五年多了,今天在此对nginx的使用做一简单总结. 一.nginx服务简介Nginx是一个高性能的HTTP和反向代理服务 ...
- M2项目测试
更为详细的测试报告,我们会在后续整理出来. 在M1的基础上,我们新增加了两个个数据表来存放问答对以及标签信息的表:C705question表 与 tag表 第二次迭代中,我们积极地同第三组沟通,了解到 ...
- Linux内核第六节 20135332武西垚
如何描述一个进程:进程描述符的数据结构: 如何创建一个进程:内核是如何执行的,以及新创建的进程从哪里开始执行: 使用gdb跟踪新进程的创建过程. 进程的描述 操作系统三大功能: 进程管理(最核心最基础 ...
- JAVA链表中迭代器的实现
注:本文代码出自<java数据结构和算法>一书. PS:本文中类的名字定义存在问题,Link9应改为Link.LinkList9应该为LinkList.由于在同包下存在该名称,所以在后面接 ...
- 第三个Sprint冲刺第五天(燃尽图)
- Alpha冲刺之事后诸葛亮
组长博客 作业博客 项目Postmortem 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件针对的是福大学子来到食堂会犹豫不决无法决定吃什么 ...
- id生成工具类
import java.util.Random; /** * 各种id生成策略 * <p>Title: IDUtils</p> * <p>Description: ...
- wamp升级php5.3.10到5.4.31版本
wamp升级php5.3.10到5.4.31版本 1. 停止WAMP服务器. 2. 去网站windows.php.net 下载php-5.4.31-nts-Win32-VC9-x86.zip. 不 ...
- ESXi安装时遇到不识别的硬件的处理
1. 部门新购置了一台inspur 四路 NF8480M4的服务器. 上架之后发现ESXi的标准安装盘无法安装. 找不到磁盘安装介质. 2. 处理办法, 找浪潮专家服务,报上序列号,要上相关的一些软件 ...
- 转《js闭包与内存泄漏》
首先,能导致内存泄漏的一定是引用类型的变量,比如函数和其他自定义对象.而值类型的变量是不存在内存泄漏的,比如字符串.数字.布尔值等.因为值类型是靠复制来传递的,而引用类型是靠类似c语言中的指针来传递的 ...