Jsf 由于ViewExpiredException,注销后需要登录两次
我在WebSphereProcessServer上有一个JSF页面(位于WAS7之上),其中包含ViewExpiredException。发生这种情况时,我希望用户先注销,然后再重新登录 我已在web.xml中设置了此异常的重定向到以下注销页面:Jsf 由于ViewExpiredException,注销后需要登录两次,jsf,websphere,viewexpiredexception,Jsf,Websphere,Viewexpiredexception,我在WebSphereProcessServer上有一个JSF页面(位于WAS7之上),其中包含ViewExpiredException。发生这种情况时,我希望用户先注销,然后再重新登录 我已在web.xml中设置了此异常的重定向到以下注销页面: <% session.invalidate(); response.sendRedirect("ibm_security_logout?logoutExitPage=/faces/ToDosOpen.jsp"); %> 然
<%
session.invalidate();
response.sendRedirect("ibm_security_logout?logoutExitPage=/faces/ToDosOpen.jsp");
%>
然后重定向到登录页面:
<%@ page import="com.ibm.wbit.tel.client.jsf.infrastructure.Messages, java.util.Locale" language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<%
String contextPath = request.getContextPath();
Locale locale = request.getLocale();
final String SECURITY_CHECK = "j_security_check";
%>
...
</head>
<body>
...
<h1><%= Messages.getString("LOGIN_LINE", locale) %></h1>
<div class="help-text"><%= Messages.getString("LOGIN_LINE_DESCR", locale) %></div>
<form target="_top" method="POST" action=<%= SECURITY_CHECK %>>
<table id="login-form">
<tr>
<td><%= Messages.getString("LOGIN_NAME", locale) %>:</td>
<td><input type="text" name="j_username"></td>
</tr>
<tr>
<td><%= Messages.getString("LOGIN_PASSWORD", locale) %>:</td>
<td><input type="password" name="j_password"></td>
</tr>
<tr>
<td id="login-button" colspan="2">
<input type="submit" name="login" value="
<%= Messages.getString("BUTTON_LOGIN", locale) %>"></td>
</tr>
</table>
</form>
...
...
:
:
当你登录时,你会被重定向到最初导致异常的页面。除非实际发生的是再次抛出异常,然后返回登录页面
所以你必须登录两次
不知道该怎么办,也不知道从哪里开始寻找。任何帮助都将不胜感激。
我已经仔细研究了这方面存在的问题,但未能解决它
编辑:我忘了提到,如果触发异常的操作是刷新,则此操作可以正常工作,但如果该操作单击命令栏,则会失败(必须登录两次)。最终使用以下ViewHandler解决了此问题。 这基本上重新创建了过期的视图。在有POST参数的情况下,它们显然已丢失,因此任何没有它们无法创建的视图都需要特殊处理 希望这对任何遇到这个问题的人都有用,如果你发现这个解决方案有什么问题,请告诉我,因为我对它没有100%的信心
/**
* This class just handles cases where the session expired
* which causes an exception on reload.
*/
public class ViewExpiredHandler extends ViewHandlerWrapper {
private ViewHandler wrapped;
public ViewExpiredHandler(ViewHandler wrapped) {
this.wrapped = wrapped;
}
@Override
public UIViewRoot restoreView( FacesContext ctx, String viewId )
{
UIViewRoot viewRoot = super.restoreView( ctx, viewId );
try {
if ( viewRoot == null) {
viewRoot = super.createView( ctx, viewId );
ctx.setViewRoot( viewRoot );
}
} catch (Exception e) {
e.printStackTrace();
}
return viewRoot;
}
@Override
protected ViewHandler getWrapped() {
return wrapped;
}
}
所以我只需要捕获ViewExpiredException,然后调用restoreView方法来传递正确的上下文和视图ID?或者有一个特殊的地方可以使用它?嗯,我的解决方案是为ViewExpiredException创建一个ViewHandler,并在其中调用restoreView。所以那是使用它的特别地方。“restoreView”方法来自ViewHandler本身(请注意“super”),因此我不确定除了在视图处理程序中之外,还可以在哪里调用它。您可能无法在JSF生命周期的每个阶段都做到这一点,但我不能说具体哪个阶段允许这样做。在还原视图阶段调用处理程序,以便该阶段正常,其他阶段可能不正常。确定。我要试试。谢谢