Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jsf 由于ViewExpiredException,注销后需要登录两次_Jsf_Websphere_Viewexpiredexception - Fatal编程技术网

Jsf 由于ViewExpiredException,注销后需要登录两次

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"); %> 然

我在WebSphereProcessServer上有一个JSF页面(位于WAS7之上),其中包含ViewExpiredException。发生这种情况时,我希望用户先注销,然后再重新登录 我已在web.xml中设置了此异常的重定向到以下注销页面:

<%  
  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生命周期的每个阶段都做到这一点,但我不能说具体哪个阶段允许这样做。在还原视图阶段调用处理程序,以便该阶段正常,其他阶段可能不正常。确定。我要试试。谢谢