Java 在Spring会话到期之前执行自定义事件

Java 在Spring会话到期之前执行自定义事件,java,spring,hibernate,session,spring-mvc,Java,Spring,Hibernate,Session,Spring Mvc,我是Spring框架的初学者 在我的情况下,会话可以通过以下方式过期 -->成功注销(显式注销) -->会话超时(隐式注销) 每当有用户登录时,我就在数据库中执行DML(记录插入),每当用户会话超时(隐式注销)时,我就要在数据库中执行DML(记录删除) 我的问题是,春天有没有办法在会议结束前告诉我们。 因此,我可以在会话到期之前执行自定义事件 提前谢谢是的,你可以用 @组件 公共类SessionEndListener实现ApplicationListener{ @凌驾 Application e

我是Spring框架的初学者

在我的情况下,会话可以通过以下方式过期
-->成功注销(显式注销)

-->会话超时(隐式注销)

每当有用户登录时,我就在数据库中执行DML(记录插入),每当用户会话超时(隐式注销)时,我就要在数据库中执行DML(记录删除)

我的问题是,春天有没有办法在会议结束前告诉我们。 因此,我可以在会话到期之前执行自定义事件

提前谢谢

是的,你可以用

@组件
公共类SessionEndListener实现ApplicationListener{
@凌驾
Application event(SessionDestroyeEvent事件)上的公共无效
{
对于(SecurityContext SecurityContext:event.getSecurityContext())
{
Authentication=securityContext.getAuthentication();
YourPrincipalClass用户=(YourPrincipalClass)身份验证。getPrincipal();
//做点什么
}
}
}
在web.xml中:

<listener>
    <listener-class>
        org.springframework.security.web.session.HttpSessionEventPublisher
    </listener-class>
</listener>

org.springframework.security.web.session.HttpSessionEventPublisher

对于常规注销和会话超时,都将触发此事件。

我已按照类似@Codo-answer的方式解决了我的问题

@Component
public class SessionCreatedListenerService implements ApplicationListener<ApplicationEvent> {

private static final Logger logger = LoggerFactory
        .getLogger(SessionCreatedListenerService.class);

@Autowired
HttpSession httpSession;



@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
    if(applicationEvent instanceof HttpSessionCreatedEvent){ //If event is a session created event



     }else if(applicationEvent instanceof HttpSessionDestroyedEvent){ //If event is a session destroy event
        // handler.expireCart();

         logger.debug(""+(Long)httpSession.getAttribute("userId"));

         logger.debug(" Session is destory  :" ); //log data

     }else if(applicationEvent instanceof AuthenticationSuccessEvent){ //If event is a session destroy event
         logger.debug("  athentication is success  :" ); //log data
     }else{
         /*logger.debug(" unknown event occur  : " Source: " + ); //log data
     }  
}   
}
@组件
公共类SessionCreatedListenerService实现ApplicationListener{
专用静态最终记录器记录器=记录器工厂
.getLogger(SessionCreatedListenerService.class);
@自动连线
HttpSession HttpSession;
@凌驾
ApplicationEvent上的公共无效(ApplicationEvent ApplicationEvent){
if(HttpSessionCreateEvent的applicationEvent instanceof){//if事件是会话创建的事件
}else if(HttpSessionDestroyeEvent的applicationEvent instanceof HttpSessionDevent){//if事件是会话销毁事件
//handler.expireCart();
logger.debug(“+(长)httpSession.getAttribute(“userId”);
debug(“会话是破坏性的:”;//日志数据
}else if(applicationEvent instanceof AuthenticationSuccessEvent){//if事件是会话销毁事件
debug(“A提示成功:”;//日志数据
}否则{
/*debug(“发生未知事件:”源:“+);//日志数据
}  
}   
}
导入org.springframework.context.ApplicationListener;
导入org.springframework.security.authentication.event.LogoutSuccessEvent;
导入org.springframework.stereotype.Component;
@组成部分
公共类LogoutSuccessListener实现ApplicationListener{
@凌驾
Application Event上的公共无效(LogoutSuccessEvent evt){
字符串login=evt.getAuthentication().getName();
System.out.println(login+“刚刚注销”);
} 
}

这很危险..如果你错过了通知怎么办?如果你的应用程序在用户会话处于活动状态时出现故障怎么办?那么我下一步该怎么办?这取决于你在数据库中存储的记录以及这些记录的重要性..什么是你不能做的?除非你破解了你正在使用的特定应用程序服务器,否则你不是能够在事件发生之前获取事件,您可以在事件发生期间或之后获取事件。是的,我得到了解决方案@Codo。您的回答很有帮助。如果我采用这种方法,我是否需要依赖项中的“Spring Security”组件。在看到需要注册的侦听器后,我遇到了这个问题。我有一个Spring启动应用程序,我实现了如上所述,SessionEndedListener用于捕获SessionDestroyEvent。我不必将HttpSessionEventPublisher注册为侦听器,我只是想了解它是如何工作的?这对我不起作用,我必须使用@EnableSpringHttpSession注释还是在某处注册应用程序侦听器?我需要启用sessionRe吗假设?在Spring Boot应用程序中的会话销毁事件期间,我可以看到applicationEvent仅是SessionDestroyedEvent的和instanceof,而不是解决方案中提到的HttpSessionDestroyedEvent。这有什么区别吗?
HttpSessionDestroyedEvent
是SessionDestroyed的直接子类事件正如您在Better to use LogoutSuccessEvent的文档中所看到的。对我来说,它工作正常,这是一个通用的解决方案
@Component
public class SessionCreatedListenerService implements ApplicationListener<ApplicationEvent> {

private static final Logger logger = LoggerFactory
        .getLogger(SessionCreatedListenerService.class);

@Autowired
HttpSession httpSession;



@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
    if(applicationEvent instanceof HttpSessionCreatedEvent){ //If event is a session created event



     }else if(applicationEvent instanceof HttpSessionDestroyedEvent){ //If event is a session destroy event
        // handler.expireCart();

         logger.debug(""+(Long)httpSession.getAttribute("userId"));

         logger.debug(" Session is destory  :" ); //log data

     }else if(applicationEvent instanceof AuthenticationSuccessEvent){ //If event is a session destroy event
         logger.debug("  athentication is success  :" ); //log data
     }else{
         /*logger.debug(" unknown event occur  : " Source: " + ); //log data
     }  
}   
}
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.LogoutSuccessEvent;
import org.springframework.stereotype.Component;

@Component 

public class LogoutSuccessListener implements ApplicationListener<LogoutSuccessEvent>{

    @Override
    public void onApplicationEvent(LogoutSuccessEvent evt) {
         String login = evt.getAuthentication().getName();
         System.out.println(login + " has just logged out");
    } 
}