繁体   English   中英

无法从JSF Phaselistener重定向

[英]Failing to redirect from JSF phaselistener

我的问题与此处的问题类似,但不涉及PrimeFaces 另外,我在那里找不到真正的解决方案。

我基本上是在没有JSF会话的情况下,试图使阶段侦听器重定向到登录页面(例如,会话已超时)

我正在尝试从JSF 2 Phaselistener中重定向。 总而言之,我正在做的是这样的:

public void beforePhase(PhaseEvent event) {
    PhaseId id = event.getPhaseId();
    if(id.equals(PhaseId.RESTORE_VIEW)){
        FacesContext context = event.getFacesContext();
        Map<String, Object> sessionMap = context.getExternalContext().getSessionMap();
        if(sessionMap==null || sessionMap.isEmpty()){
            // No Session, Redirect to login
            try {
                context.getExternalContext().redirect("/login");
            } catch (Exception e) {
                ...
            }
        }
    }
}

当重定向代码运行时,出现以下异常:

java.lang.NullPointerException
        at org.apache.myfaces.context.servlet.PartialViewContextImpl.getPartialResponseWriter(PartialViewContextImpl.java:301)
        at org.apache.myfaces.context.servlet.ServletExternalContextImpl.redirect(ServletExternalContextImpl.java:452)
        at com.AuthenticationPhaseListener.userIsNotLogedIn

是什么原因造成的? 我做错了吗?

谢谢!

这似乎是在ajax请求期间发生的。 我不确定确切的原因,stacktrace至少表明MyFaces实现中可能存在错误。

至少,总体设计方法很差。 这种HTTP请求/响应修改最好不要PhaseListener 那里不适合。 您想在普通的Servlet Filter执行这种工作。

好吧,我遇到了像您一样的问题,但是我并没有像您所做的那样以复杂的方式解决问题。

1) create a class that implements the PhaseListener
import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;

/**
 *
 * @author fakumawah @date 09.03.2012
 */
public class LoggedInCheck extends BackingBean implements PhaseListener
{

@Override`enter code here`
 public PhaseId getPhaseId()
  {
    return PhaseId.ANY_PHASE;
  }

  @Override
  public void beforePhase(PhaseEvent event)
  {
  }

  @Override
  public void afterPhase(PhaseEvent event)
  {
    FacesContext fc = event.getFacesContext();
    boolean loginPage = fc.getViewRoot().getViewId().lastIndexOf("login") > -1 ? true :     false;
    if (!loginPage && !loggedIn())
    {
      NavigationHandler nh = fc.getApplication().getNavigationHandler();
      nh.handleNavigation(fc, null, "gotologin");
    }
  }

  private boolean loggedIn()
  {
    return getSessionWrapper().isLoggedInAgain();
  }
}

对不起,未注释的代码很抱歉,但是我想代码真的很容易理解。 需要注意的最重要的事情是afterPhase(..),它检查我是否已登录或是否已有会话。 如果我不这样做,它将创建一个导航器并将我导航到登录页面

2)您的isLoggedInAgain()应该看起来像这样:

/**
   * A method to check if Username is already logged in
   * @param username
   * @return 
   */
  public boolean isLoggedInAgain()
  {
    if (session != null) // Check if session is not null
    {
      if (session.isConnected()) // Check if session is connected   
      {
        return true;
        //destroyIfsLibrarySession();  // Session is available -> destroy session
      }
      else  // session is not available
      {
        logger.log(Level.SEVERE, "Already logged out");
        return false;
      }
    }
    return false;
  }

由于我正在处理来自Oracle CMSDK的LibrarySession,因此我对该会话的测试如下所示。 最重要的是,以某种方式检查您的会话,并根据会话是否存在给出正确或错误的答案。

3)在faces-config.xml中配置侦听器

<!-- Phase-Listener to check if user is logged in or not -->
<lifecycle>
    <phase-listener>com.mycompany.mypackagename.webapp.LoggedInCheck</phase-listener>
</lifecycle>

4)最后,为“ gotologin”定义一个导航规则

<!-- Navigation Rule for sending user to login page from an expired session -->
    <navigation-rule>
        <from-view-id>*</from-view-id>
        <navigation-case>
            <from-outcome>gotologin</from-outcome>
            <to-view-id>/login.em</to-view-id>
            <redirect />
        </navigation-case>
    </navigation-rule>

就是这样,只要您在任何页面上都没有会话并且不在登录页面上,就会被带到登录页面。

请享用

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM