2011-12-20 24 views
0

私の問題はhereと似ていますが、何らかの形でPrimeFacesは含まれていません。また、私は本当の解決策を見つけることができませんでした。JSF phaselistenerからのリダイレクトに失敗しました

私は基本的に私は、JSF内からリダイレクトしようとしている

(例えば、セッションがタイムアウトした場合には、)は、JSFセッションが存在しない場合のログインページにリダイレクトするのPhaseListenerを取得しようとしている

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 

これを引き起こしている可能性が何を?私はこれを間違っているのですか?

ありがとう!

答えて

3

これは、Ajaxリクエスト中に発生しているようです。私は正確な原因がわからないので、少なくともstacktraceはMyFaces実装のバグを示しています。

少なくとも、全体的な設計手法は貧弱です。この種のHTTPリクエスト/レスポンスの変更は、好ましくはでなく、PhaseListenerにあるであるべきです。そこには意図されていません。代わりに、普通のservlet Filterでこの種の仕事をしたいとします。

+0

しかし、私はどのようにフィルタ内からJSFのセッション状態をチェックしますか? – Ben

+0

'request.getSession(false)'だけです。 JSFは、基本的にServlet APIの基本的な抽象レイヤーです。 'ExternalContext#getSessionMap()'は 'HttpSession'の属性に対応しています。 – BalusC

1

まあ、私はあなたのような同じ問題を抱えていたが、あなたがコメントを外し、コードのために申し訳ありません

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(); 
    } 
} 

をdoing.Myステップしているが、私はコードは本当に簡単だと思いとして、私はこのような複雑な方法でで解決しませんでした理解する。注意すべき最も重要なことは、私がログインしているかどうか、またはセッションが既にあるかどうかを確認するafterPhase(..)です。私があるのOracle CMSDKからのLibrarySessionを扱っておりますので

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

:私はドント場合、それは次のようになります)ナビゲータを作成し、ログインページに

2)あなたのisLoggedInAgainを(私をナビゲートなぜセッションのための私のテストはこのように見えますか?最も重要なのは、セッションが何であるかをチェックし、セッションが存在するかどうかに応じて真または偽を出すことです。

3)最後に "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> 

のためのナビゲーション・ルールを定義し、そうでないときはいつでも、それである)

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

4のfaces-config.xmlでリスナーの構成どのページにもセッションがあり、ログインページにない場合は、ログインページに移動します。

お楽しみください

+0

すばらしい答え。ありがとう!私は後で詳しく解説します。 – Ben

関連する問題