Как получить CDI-компонент SessionScoped из фильтра?

Этот вопрос связан с предыдущим вопросом о написании обработчика времени ожидания сеанса. .

Ответ в этом потоке включал доступ к различным управляемым компонентам в области сеанса из сервлета. Рекомендация (как видно здесь) состоит в том, чтобы сделать это в фильтр:

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

Предположительно, это извлекает сессионный компонент класса User. Проблема в том, что это не работает.

Что не так, так это то, что 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("login") не работает.

Кто-нибудь может сказать, как получить доступ к базовому управляемому компоненту? Я бы предпочел сделать это без привязки к Weld, но это может оказаться невозможным.


person AlanObject    schedule 19.10.2011    source источник


Ответы (1)


Этот подход работает только для сеанса JSF @ManagedBean, но не для CDI @Named bean-компонента.

Вам нужно @Inject указать его как свойство фильтра .

@Inject
private User user;
person BalusC    schedule 19.10.2011
comment
BalusC, ты когда-нибудь спишь? Я только что попытался аннотировать свой фильтр с помощью @Named и выполнить @Inject моего bean-компонента Login. Это сработало! Я понятия не имел, что служба CDI будет работать в Фильтре. Я полагаю, это означает, что объект Filter создается для каждого цикла запроса, а не только один раз за время существования сервлета. - person AlanObject; 19.10.2011
comment
Сейчас только 21:02 :) Это должно работать, если вы аннотируете фильтр с помощью @WebFilter. Я бы предпочел не делать его @Named (аналогично, @Inject должен работать и в @WebServlet сервлетах). CDI - это скорее прокси. Объекты внедряются на основе локального потока, экземпляр для внедрения не обязательно должен иметь ту же или более широкую область действия. - person BalusC; 19.10.2011
comment
@BalusC: Является ли это решение потокобезопасным, поскольку user становится членом var фильтра? - person Toru; 03.05.2018
comment
@Toru: только если вы не пропустите @Inject. - person BalusC; 13.05.2018