@ javax.faces.bean.ManagedProperty в CDI @Named bean возвращает значение null

Я пытаюсь разобраться с @javax.faces.bean.ManagedProperty, но безуспешно!

Я следил за этим руководством, и это не кажется таким уж сложным. Но мой код просто не работает!

Вот небольшой фрагмент

@ManagedBean
@SessionScoped
public class LoginBean {

    private User user;

    // ...
}
@Named
@RequestScoped
public class MessagesBean {

    @ManagedProperty(value = "#{loginBean}")
    private LoginBean loginBean;

    public String getUser() {
        System.err.println(loginBean == null);
        return loginBean.getUser().getUsername();
    }

    // ...
}

Этот код дает мне NullPointerException, говоря, что loginBean равно нулю!

Любое предложение?


person StepTNT    schedule 29.03.2012    source источник
comment
Аннотации @EJB автоматически вводят bean-компонент или как вы вводите их в LoginBean?   -  person Koray Tugay    schedule 06.05.2013


Ответы (1)


Вы смешиваете компоненты, управляемые JSF, с компонентами CDI. Ваш LoginBean - это управляемый компонент JSF (он имеет аннотацию @ManagedBean). Ваш MessageBean - это компонент CDI (он имеет аннотацию @Named). Если вы изменили компонент Message на управляемый компонент JSF (заменив @Named на @ManagedBean), проблема должна быть решена (он также должен работать с двумя компонентами CDI). Или, если вы используете JSF 2.3 или новее, используйте javax.faces.annotation.ManagedProperty вместо этого в компоненте CDI.

Вот краткий обзор того, как работает инъекция между обоими типами bean-компонентов:

CDI @Named - ›CDI @Named (работает)

CDI @Named - ›JSF @ManagedBean (работает, только если объем внедренного bean-компонента шире)

JSF @ManagedBean - ›JSF @ManagedBean (работает, только если объем внедренного bean-компонента шире)

JSF @ManagedBean - ›CDI @Named (не работает)

Но позаботьтесь о классах импорта области. Существуют разные классы для @SessionScoped и @RequestScoped в зависимости от типа bean-компонента.

javax.faces.bean.SessionScoped для @ManagedBeans

javax.enterprise.context.SessionScoped для CDI @ Именованные бобы

Кроме того, для @Named (CDI) используйте @Inject, а для @ManagedBean используйте @ManagedProperty. Есть одна вещь, которая не работает в CDI. Ваш @ManagedProperty(value = "#{loginBean}") получает полный bean-компонент, но @ManagedProperty(value = "#{loginBean.user}") получение "свойства" bean-компонента работает. Это невозможно напрямую в CDI с @Inject. См. Замена CDI для @ManagedProperty для «решения»

person Matt Handy    schedule 29.03.2012
comment
Большое спасибо ! Я уже пробовал заменить @Named на @ManagedBean, но у меня был неправильный импорт аннотации @RequestScoped, поэтому это не сработало! - person StepTNT; 29.03.2012
comment
Почему бы не пойти другим путем? Управляемые компоненты CDI обеспечивают большую гибкость и могут делать все, что могут ваши JSF ManagedBeans. См. stackoverflow.com / questions / 4347374 / - person JanM; 30.10.2013
comment
@JanM Я перехожу с управляемого бина на именованный. Вы знаете, нужно ли мне изменить EJB на Inject и ManagedProperty на Inject? Заранее спасибо. - person Ced; 20.08.2015
comment
@Ced Вам не нужно переключать @EJB на @Inject, но @ManagedProperty следует использовать только из управляемых компонентов JSF и, следовательно, не использовать в чистом контексте CDI, поэтому замените их на @Inject. - person JanM; 20.08.2015