2011-10-19 42 views
8

此问题与writing a session timeout handler上的上一个问题有关。如何从Filter中获取SessionScoped CDI bean?

该线程的答案涉及从servlet访问各种会话范围的托管bean。建议(如图here)是这样做的过滤器:

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

想必这取类用户的会话bean。问题是这不起作用。

出现问题的是bean在会话属性中存在,但它们被Weld工具包装。我写的的doFilter()方法如下:

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

当此转储出的会话属性,我通常得到的东西是这样的:

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(“登录”)不起作用。

任何人都可以说如何访问底层的托管bean吗?我宁愿以一种与Weld无关的方式来做,但这可能是不可能的。

回答

14

这种方法适用于会话范围JSF @ManagedBean,而不用于CDI @Named豆。

您需要将@Inject作为过滤器的属性。

@Inject 
private User user; 
+2

BalusC你有没有睡觉?我只是尝试使用**'@ Named' **注释我的过滤器,并对我的** Login ** bean执行**'@ Inject' **。有效!我不知道CDI服务可以在**过滤器**中工作。我想这意味着** Filter **对象为每个请求周期实例化,而不仅仅是Servlet的生命周期的一次。 – AlanObject

+1

现在只有21:02 :)如果你使用'@ WebFilter'注解过滤器,它应该可以工作。我宁愿不把它命名为@ @ Named(同样,'@Inject'也应该在'@ WebServlet' servlets中工作)。 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(); 
     }   
    } 
相关问题