2011-10-19 32 views
8

この質問は以前の質問writing a session timeout handlerに関連しています。フィルタ内からSessionScoped CDI Beanを取得するにはどうすればよいですか?

このスレッドの答えは、サーブレットからさまざまなセッションスコープのマネージドBeanにアクセスすることでした。勧告(here見られるように)フィルタでこれを行うことである。

HttpSession session = request.getSession(false); 
User user = (session != null) ? (User) session.getAttribute("user") : null; 

は、おそらくこのクラスユーザーのセッションBeanをフェッチします。問題は、これが機能しないということです。

何が間違っているのは、Beanがセッション属性にあることですが、Weld機能でラップされています。これはセッション属性をダンプするとき

public void doFilter(ServletRequest request, ServletResponse response, 
     FilterChain chain) 
     throws IOException, ServletException { 
    HttpServletRequest req = (HttpServletRequest) request; 
    HttpServletResponse res = (HttpServletResponse) response; 

    String sp = req.getServletPath(); 
    System.out.println("------------------------"); 
    System.out.println("doFilter(): " + sp); 

    if (!sp.startsWith("/javax")) { // eliminates many requests 
     HttpSession session = req.getSession(); 
     Enumeration<String> en = session.getAttributeNames(); 
     int count = 0;    
     while (en.hasMoreElements()) { 
      String e = en.nextElement(); 
      System.out.println("Attribute " + ++count + ": " + e); 
     } 
    } 
    chain.doFilter(request, response); 
} 

は、私は通常、このような何かを得る:次のように私はのdoFilter()メソッドを書いた

INFO: ------------------------ 
INFO: doFilter(): /Display.xhtml 
INFO: Attribute 1: org.jboss.weld.context.http.HttpSessionContext#org.jboss.weld.bean-WEB-INF/lib/myfaces-extcdi-bundle-jsf20-1.0.1-ManagedBean-class org.apache.myfaces.extensions.cdi.jsf.impl.scope.conversation.EditableWindowContextManagerProxy 
INFO: Attribute 2: org.jboss.weld.context.http.HttpSessionContext#org.jboss.weld.bean-MyApp5-ManagedBean-class com.app.Login 
INFO: Attribute 3: org.jboss.weld.context.conversation.ConversationIdGenerator 
INFO: Attribute 4: com.sun.faces.renderkit.ServerSideStateHelper.LogicalViewMap 
INFO: Attribute 5: org.jboss.weld.context.ConversationContext.conversations 
INFO: Attribute 6: facelets.ui.DebugOutput 
INFO: Attribute 7: javax.faces.request.charset 
INFO: Attribute 8: org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowContext:EXISTING_WINDOW_ID_LIST 

属性#2は、Beanを表すために思われますが欲しいです。言うまでもなく、session.getAttribute( "login")への呼び出しは機能しません。

基本となる管理対象Beanにアクセスする方法は誰にも分かりますか?私はWeldと結びついていない方法でやりたいと思っていますが、それは可能ではないかもしれません。

答えて

14

このアプローチは、セッションスコープのJSF @ManagedBeanのみで動作し、CDI @Named beanでは動作しません。

フィルタのプロパティとして@Injectが必要です。

@Inject 
private User user; 
+2

BalusCあなたは今まで寝ていますか?私はちょうど** @ Named' **で私のフィルターに注釈をつけて、** ** Login ** beanの** '@ Inject' **をやってみました。出来た!私はCDIサービスが** Filter **で動作するかどうか分かりませんでした。これは、** Filter **オブジェクトがサーブレットのライフタイムのためだけではなく、リクエストサイクルごとにインスタンス化されることを意味します。 – AlanObject

+1

これはほんの21:02です:)あなたは '@ WebFilter'でフィルタに注釈を付けるとうまくいくはずです。私はむしろそれを '@ Named'にしたくないでしょう(同様に、' @ Inject'も '@ WebServlet'サーブレットで動作するはずです)。 CDIはもっとプロキシです。オブジェクトはスレッドローカルベースで注入され、注入されるインスタンスは同じスコープまたはより広いスコープである必要はありません。 – BalusC

4
import org.jboss.weld.context.SerializableContextualInstanceImpl; 

    HttpSession httpSession = (HttpSession) facesContext.getExternalContext().getSession(false); 
    Enumeration<String> attribs = httpSession.getAttributeNames(); 
    String attrib = null; 
    while (attribs.hasMoreElements()) {   
     attrib = attribs.nextElement(); 
     Object obj = httpSession.getAttribute(attrib); 
     if(obj instanceof SerializableContextualInstanceImpl){ 
      SerializableContextualInstanceImpl impl = (SerializableContextualInstanceImpl)obj; 
      //here: MyObject myObj= (MyObject)impl.getInstance(); 
     }   
    } 
関連する問題