CDI/JSF如何处理会话超时
我有一个jakarta EE8(CDI 2 / WELD / JSF 2.3 / WILDFLY)应用程序,在该应用程序中,我需要在用户注销时执行一些清理代码,手动注销还可以,但是现在我需要在会话自动发生注销时启动事件超时,为了处理此问题,我已经尝试了以下两种方法...
@Named
@SessionScoped
public class HttpSessionObservers implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Inject private Logger log;
@Inject SecurityContext securityContext;
@PreDestroy
public void processSessionScopedDestroying() {
log.debug("Http Session predestroy");
Principal principal = securityContext.getCallerPrincipal(); //<----is null
//...do some cleanup/logging operations on user account
}
}
上面的 @predestroy
在会话时间播放时呼叫射击,但是登录用户(principal)始终是无效的已经登录了,因此我无法获得用户。
@Named
public class HttpSessionObservers implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Inject private Logger log;
@Inject private Event<UserLogoutEvent> userLogoutEvent;
public void processSessionScopedInit(@Observes @Initialized(SessionScoped.class) HttpSession payload) {
log.debug("Http Session initialised");
}
public void processSessionScopedDestroying(@Observes @BeforeDestroyed(SessionScoped.class) HttpSession payload) {
//Never fires
log.debug("Http Session predestroy");
Principal principal = securityContext.getCallerPrincipal();
//...do some cleanup/logging operations on user account
}
public void processSessionScopedDestroyed(@Observes @Destroyed(SessionScoped.class) HttpSession payload) {
log.debug("Http Session destroyed");
}
}
在这里,@beforedestroy的事件从未被解雇,似乎找不到任何工作的示例,它确实可以适合其他范围。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
实现您自己的
httpsessionlistener
并用@weblistener
进行注释。容器应识别此问题,并将在您的实现中调用sessionDestroyed()
方法。您的课程有资格参加CDI注入,因此在sessiondestroyed()
中,您可以发射事件并与CDI观察者一起收听。参考:
编辑:
然后尝试以下操作:范围:
httpsessionlistener
inmand inmand to@ApplicationsCoped 。具有SessionID/用户名的同步图。在
sessionCreated()中,
插入地图中,然后在sessionDestroyed()
中将其删除在最后
block中。该容器还将有几个隐式
httpsessionListener
s,因此在会话无效之后很长时间您的最后一个被称为您的最后一次。如果这样,您可以使用另一种技术来插入您的httpsessionListener
inmpriond。首先尝试上述技术,然后我们可以深入研究。Implement your own
HttpSessionListener
and annotate it with@WebListener
The container should recognize this and will call the thesessionDestroyed()
method in your implementation. Your class is eligible for CDI Injection so insessionDestroyed()
, you can fire an event and listen for it with a CDI Observer.Ref: https://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpSessionListener.html
EDIT:
Try this then: Scope your
HttpSessionListener
impl to@ApplicationScoped
. Have a synchronized Map of sessionId/username. InsessionCreated()
insert into the map, and onsessionDestroyed()
remove it in afinally
block.The container will also have several implicit
HttpSessionListener
s, so there's a chance yours is being called last long after the session is invalidated. If thats the case, there's another technique you can use to insert yourHttpSessionListener
impl first. Try the above technique first then we can dive into this.