HttpSessionBindingListener.valueUnbound 未在会话超时时触发
HttpSessionBindingListener.valueUnbound is not triggered on session timeout
我们需要在会话超时时进行一些数据库清理,因此实现了 HttpSessionBindingListener 并在用户登录时向会话添加了一个对象,我们从不明确地将其从会话中删除。
HttpSessionBindingListener.valueUnbound 如果我们手动调用 session.invalidate 会触发,但问题是它不会在会话超时时触发。我在控制台中看到一个错误,但不确定是什么问题。
在登录时将对象设置为会话并在注销时使会话无效:
@Named("logincontroller")
@Stateful
public class LoginController implements ILoginController, Serializable {
@Inject
private Credentials credentials;
private ExternalContext ec = null;
private HttpServletRequest request =null;
private HttpServletResponse response=null;
private HttpSession session=null;
@PostConstruct
private void getLocalVariables() {
ec = FacesContext.getCurrentInstance().getExternalContext();
request= (HttpServletRequest)ec.getRequest();
session = request.getSession();
}
@Override
public boolean login() {
...
credentials.setUserName(getUserName().toUpperCase());
credentials.setUserPassword(getPassword());
// set the object into session on user login
session.setAttribute("credentials", credentials);
}
@Override
public void logout() {
...
try {
response.sendRedirect(path+"/faces/Exit.html");
// invalidate the session on logout
session.invalidate();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
实现 HttpSessionBindingListener 的凭据对象
@Named("credentials")
@SessionScoped
public class Credentials implements ICredentials, Serializable, HttpSessionBindingListener {
...
@Override
public void valueBound(HttpSessionBindingEvent event) {
//do nothing
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
try {
// run DB scripts to clean up
lockManager.releaseAllLocksForUser(getUserName().toUpperCase());
} catch (Exception e) {
e.printStackTrace();
}
}
}
错误堆栈跟踪:
15:13:03,252 INFO [org.jboss.as.repository] (ServerService Thread Pool -- 66) WFLYDR0009: Content C:<path>jbossstudio10\runtimes\jboss-eap\standalone\data\contentccffda3936daab4d3148eb2e51584f8372592 is obsolete and will be removed
15:13:03,299 INFO [org.jboss.as.repository] (ServerService Thread Pool -- 66) WFLYDR0002: Content removed from location C:\<path>\jbossstudio10\runtimes\jboss-eap\standalone\data\contentccffda3936daab4d3148eb2e51584f8372592\content
15:26:36,245 ERROR [stderr] (default task-22) Exception in thread "default task-22" org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.SessionScoped
15:26:36,246 ERROR [stderr] (default task-22) at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:689)
15:26:36,246 ERROR [stderr] (default task-22) at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:90)
15:26:36,246 ERROR [stderr] (default task-22) at org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:165)
15:26:36,246 ERROR [stderr] (default task-22) at org.jboss.weld.bean.ContextualInstance.getIfExists(ContextualInstance.java:63)
15:26:36,246 ERROR [stderr] (default task-22) at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:83)
15:26:36,246 ERROR [stderr] (default task-22) at org.jboss.weld.bean.proxy.ProxyMethodHandler.getInstance(ProxyMethodHandler.java:125)
15:26:36,246 ERROR [stderr] (default task-22) at com.facility.security.Credentials$Proxy$_$$_WeldClientProxy.valueUnbound(Unknown Source) // unknown source??
15:26:36,246 ERROR [stderr] (default task-22) at io.undertow.servlet.core.SessionListenerBridge.attributeRemoved(SessionListenerBridge.java:132)
15:26:36,247 ERROR [stderr] (default task-22) at io.undertow.server.session.SessionListeners.attributeRemoved(SessionListeners.java:81)
15:26:36,247 ERROR [stderr] (default task-22) at io.undertow.server.session.InMemorySessionManager$SessionImpl.removeAttribute(InMemorySessionManager.java:500)
15:26:36,247 ERROR [stderr] (default task-22) at io.undertow.servlet.core.SessionListenerBridge.sessionDestroyed(SessionListenerBridge.java:72)
15:26:36,247 ERROR [stderr] (default task-22) at io.undertow.server.session.SessionListeners.sessionDestroyed(SessionListeners.java:61)
15:26:36,248 ERROR [stderr] (default task-22) at io.undertow.server.session.InMemorySessionManager$SessionImpl.invalidate(InMemorySessionManager.java:528)
15:26:36,248 ERROR [stderr] (default task-22) at io.undertow.server.session.InMemorySessionManager$SessionImpl.run(InMemorySessionManager.java:357)
15:26:36,248 ERROR [stderr] (default task-22) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
15:26:36,248 ERROR [stderr] (default task-22) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
15:26:36,248 ERROR [stderr] (default task-22) at java.lang.Thread.run(Thread.java:748)
我是否需要在 valueUnbound 中获取一个新会话到 运行 我的数据库脚本?我认为在调用 valueUnbound 时我们仍然有会话。我确实搜索了 Whosebug,但无济于事。
非常感谢任何帮助。
环境:Windows 7 Enterrpise,JDK 1.8,JBoss EAP 7.0.0,CDI 1.2,Mojarra 2.2.12-jbossorg-2,deltaspike 1.8.1,Servlets 3.1,PrimeFaces 6.1,甲骨文 11g
我从未真正使用过 HttpSessionBindingListener.valueUnbound
,但看起来事件的顺序在 CDI 和 servlet 行为之间有点混乱。具体来说,它看起来像 CDI 被告知在调用 HttpSessionBindingListener.valueUnbound
之前拆除会话 bean。因此异常 - 当应该调用该方法时,您不再有会话上下文活动。
可能的解决方案是扭曲您的代码并且不使用 HttpSessionBindingListener.valueUnbound
而是使Credentials.valueUnbound
成为@PreDestroy
方法。这样,只要该 bean 将被销毁,CDI 就应该调用它,无论原因是会话失效还是超时。
我们需要在会话超时时进行一些数据库清理,因此实现了 HttpSessionBindingListener 并在用户登录时向会话添加了一个对象,我们从不明确地将其从会话中删除。
HttpSessionBindingListener.valueUnbound 如果我们手动调用 session.invalidate 会触发,但问题是它不会在会话超时时触发。我在控制台中看到一个错误,但不确定是什么问题。
在登录时将对象设置为会话并在注销时使会话无效:
@Named("logincontroller")
@Stateful
public class LoginController implements ILoginController, Serializable {
@Inject
private Credentials credentials;
private ExternalContext ec = null;
private HttpServletRequest request =null;
private HttpServletResponse response=null;
private HttpSession session=null;
@PostConstruct
private void getLocalVariables() {
ec = FacesContext.getCurrentInstance().getExternalContext();
request= (HttpServletRequest)ec.getRequest();
session = request.getSession();
}
@Override
public boolean login() {
...
credentials.setUserName(getUserName().toUpperCase());
credentials.setUserPassword(getPassword());
// set the object into session on user login
session.setAttribute("credentials", credentials);
}
@Override
public void logout() {
...
try {
response.sendRedirect(path+"/faces/Exit.html");
// invalidate the session on logout
session.invalidate();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
实现 HttpSessionBindingListener 的凭据对象
@Named("credentials")
@SessionScoped
public class Credentials implements ICredentials, Serializable, HttpSessionBindingListener {
...
@Override
public void valueBound(HttpSessionBindingEvent event) {
//do nothing
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
try {
// run DB scripts to clean up
lockManager.releaseAllLocksForUser(getUserName().toUpperCase());
} catch (Exception e) {
e.printStackTrace();
}
}
}
错误堆栈跟踪:
15:13:03,252 INFO [org.jboss.as.repository] (ServerService Thread Pool -- 66) WFLYDR0009: Content C:<path>jbossstudio10\runtimes\jboss-eap\standalone\data\contentccffda3936daab4d3148eb2e51584f8372592 is obsolete and will be removed
15:13:03,299 INFO [org.jboss.as.repository] (ServerService Thread Pool -- 66) WFLYDR0002: Content removed from location C:\<path>\jbossstudio10\runtimes\jboss-eap\standalone\data\contentccffda3936daab4d3148eb2e51584f8372592\content
15:26:36,245 ERROR [stderr] (default task-22) Exception in thread "default task-22" org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.SessionScoped
15:26:36,246 ERROR [stderr] (default task-22) at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:689)
15:26:36,246 ERROR [stderr] (default task-22) at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:90)
15:26:36,246 ERROR [stderr] (default task-22) at org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:165)
15:26:36,246 ERROR [stderr] (default task-22) at org.jboss.weld.bean.ContextualInstance.getIfExists(ContextualInstance.java:63)
15:26:36,246 ERROR [stderr] (default task-22) at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:83)
15:26:36,246 ERROR [stderr] (default task-22) at org.jboss.weld.bean.proxy.ProxyMethodHandler.getInstance(ProxyMethodHandler.java:125)
15:26:36,246 ERROR [stderr] (default task-22) at com.facility.security.Credentials$Proxy$_$$_WeldClientProxy.valueUnbound(Unknown Source) // unknown source??
15:26:36,246 ERROR [stderr] (default task-22) at io.undertow.servlet.core.SessionListenerBridge.attributeRemoved(SessionListenerBridge.java:132)
15:26:36,247 ERROR [stderr] (default task-22) at io.undertow.server.session.SessionListeners.attributeRemoved(SessionListeners.java:81)
15:26:36,247 ERROR [stderr] (default task-22) at io.undertow.server.session.InMemorySessionManager$SessionImpl.removeAttribute(InMemorySessionManager.java:500)
15:26:36,247 ERROR [stderr] (default task-22) at io.undertow.servlet.core.SessionListenerBridge.sessionDestroyed(SessionListenerBridge.java:72)
15:26:36,247 ERROR [stderr] (default task-22) at io.undertow.server.session.SessionListeners.sessionDestroyed(SessionListeners.java:61)
15:26:36,248 ERROR [stderr] (default task-22) at io.undertow.server.session.InMemorySessionManager$SessionImpl.invalidate(InMemorySessionManager.java:528)
15:26:36,248 ERROR [stderr] (default task-22) at io.undertow.server.session.InMemorySessionManager$SessionImpl.run(InMemorySessionManager.java:357)
15:26:36,248 ERROR [stderr] (default task-22) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
15:26:36,248 ERROR [stderr] (default task-22) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
15:26:36,248 ERROR [stderr] (default task-22) at java.lang.Thread.run(Thread.java:748)
我是否需要在 valueUnbound 中获取一个新会话到 运行 我的数据库脚本?我认为在调用 valueUnbound 时我们仍然有会话。我确实搜索了 Whosebug,但无济于事。
非常感谢任何帮助。 环境:Windows 7 Enterrpise,JDK 1.8,JBoss EAP 7.0.0,CDI 1.2,Mojarra 2.2.12-jbossorg-2,deltaspike 1.8.1,Servlets 3.1,PrimeFaces 6.1,甲骨文 11g
我从未真正使用过 HttpSessionBindingListener.valueUnbound
,但看起来事件的顺序在 CDI 和 servlet 行为之间有点混乱。具体来说,它看起来像 CDI 被告知在调用 HttpSessionBindingListener.valueUnbound
之前拆除会话 bean。因此异常 - 当应该调用该方法时,您不再有会话上下文活动。
可能的解决方案是扭曲您的代码并且不使用 HttpSessionBindingListener.valueUnbound
而是使Credentials.valueUnbound
成为@PreDestroy
方法。这样,只要该 bean 将被销毁,CDI 就应该调用它,无论原因是会话失效还是超时。