[英]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.