我有一个用例场景,用户从应用程序注销,然后将她重定向到登录页面index.xhtml
,但没有关闭该浏览器选项卡。一段时间后,她尝试从同一选项卡再次登录。之后,将抛出ViewExpiredException
。
在这种用例情况下,我希望应用程序刷新索引页面,并使用户能够再次登录。我以为我应该抓住ViewExpiredException
,将网络浏览器转发到错误页面,在该页面上可以通知用户有关此会话错误的信息,然后再次将浏览器重定向到索引页面。
按照https://stackoverflow.com/a/3642969/6359607页上的“处理ViewExpiredException”段落下的说明,我具有以下配置:
web.xml
内:<error-page>
<error-code>404</error-code>
<location>/WEB-INF/errors/expired.xhtml</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/WEB-INF/errors/general.xhtml</location>
</error-page>
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/WEB-INF/errors/expired.xhtml</location>
</error-page>
faces-config.xml
内:<factory>
<exception-handler-factory>org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory</exception-handler-factory>
</factory>
expired.xhtml
看起来像这样:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<ui:composition template="/templates/page-template.xhtml">
<ui:param name="pageTitle" value="Session is expired!" />
<ui:define name="html-head">
<meta http-equiv="refresh" content="3;url=#{request.contextPath}/index.xhtml?faces-redirect=true" />
</ui:define>
<ui:define name="panel-main">
<p>
<a href="#{request.contextPath}/index.xhtml?faces-redirect=true">
If the redirection doesn't work click here.
</a>
</p>
</ui:define>
</ui:composition>
</html>
当查看会话期满后用户尝试登录index.xhtml
页面时,应用程序将抛出javax.faces.application.ViewExpiredException
:
SEVERE [org.omnifaces.exceptionhandler.FullAjaxExceptionHandler] (default task-12) [d358fee4-9640-48b4-9c82-e97add8dfc84][127.0.0.1]
FullAjaxExceptionHandler: An exception occurred during processing JSF ajax request. Error page '/WEB-INF/errors/expired.xhtml' will be shown.:
javax.faces.application.ViewExpiredException: viewId:/index.xhtml - View /index.xhtml could not be restored.
at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:218)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:133)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:201)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:670)
...
之后,它将Web浏览器转发到页面expired.xhtml
(注意:浏览器URL不会更改为expired.xhtml
,而是保持index.xhtml
)。然后,该页面不会重定向到index.xhtml页面,正如我认为会根据其meta标签一样。
出于测试目的,我在web.xml
内将404错误转发到同一页面expired.xhtml
。当我在浏览器中输入一些不存在的URL时,它将转发到expired.xhtml
,然后重定向到index.xhtml
页面。
此外,当我从WEB-INF目录中移动expired.xhtml
页并直接从Web浏览器访问它时,它会正确地重定向到索引页。
在描述的用例场景中,为什么Web浏览器没有从expired.xhtml
重定向到索引页面?我该如何解决这种重定向?
我尝试了很多事情,其中包括扩展FullAjaxExceptionHandler
和FullAjaxExceptionHandlerFactory
,这些行为并没有对此行为施加任何改变。