我有一个带有menuitem元素的primefaces dock导航栏,它应该会触发我的web应用程序的注销机制,但它不起作用,我不知道为什么。有人能帮我找到当我点击菜单项时没有调用登出功能的原因吗?
这是JSF页面模板中的元素:
<h:form>
<p:dock position="top">
<p:menuitem value="Logout" icon="unsecuredimages/logout.png" action="securityController.logOut()" rendered ="#{!securityController.checkLogged}"/>
</p:dock>
</h:form>
这是logOut()方法所在的backingbean:
@ManagedBean
@RequestScoped
public class SecurityController {
...
public String logOut() {
authentificationEJB.releaseUserState();
return "main.xhtml";
}
...
这是访问会话并从记录的用户释放会话的EJB:
@Stateful(name = "ejbs/AuthentificationEJB")
public class AuthentificationEJB implements IAuthentificationEJB {
...
// Logout
public void releaseUserState() {
// 1-Check if there is something saved in the session(or wherever the
// state is saved)
if (!FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap().isEmpty()) {
// 2-If 1 then flush it
FacesContext.getCurrentInstance().release();
}
}
...
}
当我点击菜单项时,我得到了这个异常:
警告:StandardWrapperValve[FacesServlet]:PWC1406:Servlet.service()对于servlet Faces servlet抛出例外位于的java.lang.IollegalStateExceptioncom.sun.faces.context.FacesContextImpl.assertNotReleased(FacesContextImpl.java:639)在com.sun.faces.context.FacesContextImpl.getCurrentPhaseId(FacesContextImpl.java:515)在javax.faces.event.ExceptionQueuedEventContext.(ExceptionQueued EventContext.java:148)在javax.faces.event.ExceptionQueuedEventContext.(ExceptionQueued EventContext.java:101)在com.sun.faces.lifecycle.Phase.queueException(Phase.java:156)在com.sun.faces.lifecycle.Phase.queueException(Phase.java:149)在com.sun.faces.lifecycle.Phase.doPhase(Phase.java:109)在com.sun.faces.lifecycle.Impl.execute(LifecycleImpl.java:118)在javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)在org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)在过滤器。RestrictPageFilter.doFilter(RestrictPageFilter.java:90)在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)在org.apache.catalina.core.StandardWrapperValv.invoke(StandardWrapperValve.java:277)在org.apache.catalina.core.StandardContextValv.invoke(StandardContextValv.java:188)在org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)在com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)在com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)在org.apache.catalina.core.StandardHostValv.invoke(StandardHostValve.java:185)在org.apache.catalina.connecter.CoyoteAdapter.doService(Coyotedapter.java:325)在org.apache.catalina.connecter.CoyoteAdapter.service(Coyotedapter.java:226)在com.sun.enterprise.v3.services.impl.ContainerMaper.service(ContainerMaper.java:165)在com.sun.grazzy.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)在com.sun.grazzy.http.ProcessorTask.doProcess(ProcessorTask.java:693)在com.sun.grazzly.http.ProcessorTask.produce(ProcessorTask.java:954)在com.sun.grazzy.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)在com.sun.grazzy.DefaultProtocolChain.executeProtocolFilter(DefaultProtocol Chain.java:135)在com.sun.grazzy.DefaultProtocolChain.execute(DefaultProtocol Chain.java:102)在com.sun.grazzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)在com.sun.grazzy.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)在com.sun.grazzy.ProtocolChainTextTask.doCall(ProtocolchainTextTask.java:53)在com.sun.grazzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)在com.sun.grazzy.ContextTask.run(ContextTask.java:69)在com.sun.grazzy.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)在com.sun.grazzy.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)在java.lang.Thread.run(线程.java:662)
更新
<p:menuitem value="Logout" icon="unsecuredimages/logout.png" action="#{securityController.logOut}" rendered ="#{!securityController.checkLogged}"/>
@ManagedBean
@ViewScoped
public class SecurityController {
@EJB
private IAuthentificationEJB authentificationEJB;
private String email;
private String password;
private String notificationValue;
public String logOut() {
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
if (session != null) {
session.invalidate();
}
return "main.xhtml";
}
...
}
我不知道您是否需要release()
方法。我认为这种方法是你例外的原因。引用javadoc:
在FacesContext实例(直到FacesContext实例已由的实施回收重用),调用任何其他方法将导致非法状态异常被抛出。
实现必须调用setCurrentInstance(javax.faces.context.FacesContext)传递null以删除关联在这条线和这条死线之间FacesContext实例。
我使用以下注销方法。也许这对你有帮助:
public String logout() {
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
if (session != null) {
session.invalidate();
}
user = null; // reset user
// optional: addSuccessMessage
return "login";
}
尝试从RequestScoped更改为例如Sessions,我在使用RequestScopedbackingbeans的apst中遇到了一些问题。