2015-01-29 1 views
1

У меня есть EJB с фиксированным состоянием, связанный с сеансом (CDI), который содержит информацию о сеансе пользователя.Не удается ввести CDI @SessionScoped в HttpSessionListener

@Stateful 
@SessionScoped 
public class GestorSesion implements IGestorSesionLocal, Serializable { 

    private final static long serialVersionUID = 1L; 

    private static final Logger log = Logger.getLogger(GestorSesion.class.getName()); 

    @PostConstruct 
    private void init() { 
    log.info("Configurando información de usuario"); 
    log.info("****************************************************************************"); 
    } 

    @Override 
    public void cerrarSesion() { 
    } 

    @Override 
    public ISessionInfo getSesionInfo() { 
    return null; 
    } 
} 

Теперь я хочу, чтобы позвонить cerrarSesion() (closeSession()) из HttpSessionListener

public class GestorSesionWeb implements HttpSessionListener { 


    private static final Logger log = Logger.getLogger(GestorSesionWeb.class.getName()); 

    @Inject 
    private Instance<IGestorSesionLocal> gestorSesion; 

    @Override 
    public void sessionCreated(HttpSessionEvent se) { 
    if (log.isLoggable(Level.FINE)) { 
     log.fine("Iniciada sesión web"); 
    } 
    gestorSesion.get().getSesionInfo(); 
    } 

    @Override 
    public void sessionDestroyed(HttpSessionEvent se) { 
    if (log.isLoggable(Level.FINE)) { 
     log.fine("Limpiando sesión al salir"); 
    } 
    try { 
     this.gestorSesion.get().cerrarSesion(); 
     if (log.isLoggable(Level.FINE)) { 
     log.fine("Sesión limpiada sin problemas"); 
     } 
    } catch (Exception e) { 
     log.log(Level.WARNING, "Excepción limpiando sesión", e); 
    } 
    } 
} 

И я получить доступ к EJB из веба-приложения, непосредственно (инъекционное использование @EJB) в бобы, которые я использую для JSF (они также являются управляемыми бинами CDI).

Проблема, с которой я сталкиваюсь, состоит в том, что кажется, что HttpSessionListener, по-видимому, находится в другом «сеансовом пространстве», чем бобы JSF. Созданы два экземпляра GestorSession; один экземпляр из JSF и других, созданных из HttpSessionListener.

Я попытался впрыснуть бобов через @Inject Instance<IGestorSesionLocal>, @Inject IGestorSesionLocal и BeanManager, с одинаковыми результатами.

This bug report предполагает, что он должен работать правильно (ошибка решена для моей версии), но я все еще не могу обойти ее. Я огляделся, но я нашел Q & A, относящийся к управляемым bean-компонентам JSF (да, я мог бы попытаться привязать ссылку к EJB в управляемом компоненте JSF, но сначала я хотел бы попробовать «правильно»).

Работа с WilFly 8.1.0 и JDK 7

Любые идеи?

+0

@BalusC Я пробовал, но недействительность сессии не вызывает '@ PreDestroy'. Это либо то, что он ожидает, что bean будет тайм-аут или (как я где-то читал, но несколько сомневаюсь), что контейнер пассивит EJB и отбрасывает их, не вызывая «PreDestroy» EJB. В любом случае '@ PreDestroy' не вызывается (по крайней мере, в краткосрочной перспективе), если я не назову' @ Remove'. Я делаю это для инициированного пользователем выхода из системы, и я пытаюсь контролировать это для выхода из системы с выдержкой времени. – SJuan76

+0

Некоторые вещи выглядят не так. '@ Stateful' даст вам EJB; '@ SessionScoped' должен предоставить вам управляемый бидом CDI (я не уверен, что поведение будет без' @ Named'). Если вы имеете дело с '@ Stateful', два отдельных вызова не гарантируют вам один и тот же экземпляр EJB. Применение как '@ Stateful', так и' @ SessionScoped' в том же классе даст вам один EJB и один CDI-компонент, оба из которых не обязательно должны знать друг друга.В лучшем случае, что вы получаете, это несогласованное состояние боба. Почему вы объединяете управляемый компонент и EJB в одном определении класса? – kolossus

ответ

4

Я думаю, что ваш рь приходит отсюда:

И я получить доступ к EJB из веба-приложения, непосредственно (инъекционный использование @EJB) в бобы JSF.

При использовании CDI с EJB (поставив @Sessionscoped на него, например) вы получили CDI бобов, которое также имеет EJB природу, но не наоборот. Другими словами, CDI знает природу EJB, но EJB не знает CDI.

Так что если вы хотите ввести EJB в качестве компонента CDI в свой код, используйте @Inject, а не @EJB. Из Java EE 6 признанная хорошая практика заключается в том, чтобы всегда использовать @Inject, за исключением дистанционного EJB.

Также убедитесь, что используется только управляемый bean-компонент CDI, а не комбинация управляемых битов CDI и JSF.

+0

Спасибо за помощь! Я попробую переключить '@ EJB' на' @ Inject' в понедельник (сегодня я не в офисе). Для точки «CDI vs JSF» я был недостаточно ясен, компоненты JSF * являются * управляемыми бинами CDI (но используются для отображения страниц JSF), я исправлю это в вопросе. – SJuan76

+0

Теперь он работает как следует, спасибо. – SJuan76

 Смежные вопросы

  • Нет связанных вопросов^_^