2012-03-08 59 views
0

我在Websphere Process Server(在WAS 7之上)上有一个JSF页面,该页面有ViewExpiredException。当发生这种情况我想用户注销,然后重新登录 我已经建立了这个异常的重定向在web.xml中下面登出页面:由于ViewExpiredException在注销后需要登录两次

<% 
    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> 

而当您登录时,您将被重定向到引起异常的页面。除了实际发生的情况外,再次抛出异常,并返回到登录页面。

所以你必须登录两次。

不知道该怎么做或从哪里开始寻找。任何帮助,将不胜感激。 我已经浏览了关于此问题的现有问题,但无法解决此问题。


编辑:我忘了提,这工作得很好,如果触发异常的行动是一个刷新,但失败(不必登录两次),如果行动点击一个命令栏。

回答

0

最后使用下面的ViewHandler解决了它。 这基本上重新创建过期的视图。在有POST参数的情况下,它们显然已经丢失,因此任何无法创建的视图都需要特殊处理。

希望对于遇到此问题的其他人有用,如果您发现此解决方案有任何问题,请告诉我,因为我对此不是十分有信心。

/** 
* 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; 
} 
} 
+0

所以我只需要捕捉ViewExpiredException然后调用方法restoreView传递正确的上下文和视图ID?或者有一个特殊的地方可以使用它? – rsb2097 2014-09-17 17:56:02

+1

那么,我的解决方案是为ViewExpiredException创建一个ViewHandler,并在那里调用restoreView。所以这是使用它的特殊地方。 “restoreView”方法来自ViewHandler本身(注意“超级”),所以我不知道除了视图处理程序之外,还有哪些地方可以调用它。 您可能无法在JSF生命周期的每个阶段都这样做,但我不能说哪些阶段特别允许这样做。处理程序在Restore View阶段中调用,以便阶段良好,其他阶段可能不会。 – 2014-09-17 19:25:35

+0

好的。要尝试一下。谢谢! – rsb2097 2014-09-18 14:22:01