Невозможно @Ввести @ManagedBean в другой @ManagedBean - PullRequest
2 голосов
/ 14 марта 2011

Хорошо, вот мой сессионный компонент. Я всегда могу получить currentUser из любого сервлета или фильтра. Это не проблема Проблема в fileList и currentFile. Я тестировал с простыми int и Strings и его эффект тот же. Если я установлю значение из своего bean-объекта области видимости, я смогу получить данные из другого класса.

@ManagedBean(name = "userSessionBean")
@SessionScoped
public class UserSessionBean implements Serializable, HttpSessionBindingListener {

    final Logger logger = LoggerFactory.getLogger(UserSessionBean.class);

    @Inject
    private User currentUser;

    @EJB
    UserService userService;

    private List<File> fileList;   

    private File currentFile;

    public UserSessionBean() {

        fileList = new ArrayList<File>();
        currentFile = new File("");
    }

    @PostConstruct
    public void onLoad() {

        Principal principal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
        String email = principal.getName();

        if (email != null) {
            currentUser = userService.findUserbyEmail(email);
        } else {

            logger.error("Couldn't find user information from login!");
        }
    }

Вот пример.

Мой вид, боб видимости. Вот как это оформлено.

 @ManagedBean
 @ViewScoped
 public class ViewLines implements Serializable {

    @Inject
    private UserSessionBean userSessionBean; 

Теперь код.

    userSessionBean.setCurrentFile(file);
    System.out.println("UserSessionBean : " + userSessionBean.getCurrentFile().getName());

Я прекрасно вижу текущее имя файла. Это на самом деле печатается из метода действия JSF. Очевидно, что текущий файл установлен.

Теперь, если я сделаю это.

@WebFilter(value = "/Download")
public class FileFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {        
        HttpSession session = ((HttpServletRequest) request).getSession(false);
        UserSessionBean userSessionBean = (UserSessionBean) session.getAttribute("userSessionBean");       

        System.out.println(userSessionBean.getCurrentUser().getUserId()); //works

        System.out.println("File filter" + userSessionBean.getCurrentFile().getName()); //doesn't work


        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }
}

currentUser отображается нормально, но я не вижу файл. Это просто пусто. То же самое происходит со строками, int и т. Д.

Спасибо за любую помощь, которую вы можете оказать по этому вопросу.

ИНФОРМАЦИЯ: UserSessionBean: строка 3B - 8531268875812004316.csv (значение выводится из видового объекта bean)

ИНФОРМАЦИЯ: Фильтр файлов tester.csv (значение выводится при запуске фильтра.)

** EDIT **

Это сработало.

 FacesContext context = FacesContext.getCurrentInstance();
    userSessionBean = (UserSessionBean) context.getApplication().evaluateExpressionGet(context, "#{userSessionBean}", UserSessionBean.class);

Я поместил это в конструктор ViewScoped, и все было хорошо. Теперь, почему инъекция не делает то, что я думал? Сначала я подумал, может быть, потому что я использовал управляемые компоненты JSF вместо новых компонентов CDI. Но я изменил bean-компоненты на новый стиль (с именованным), и это был тот же эффект.

Позволяет ли inject только получать доступ к bean-компонентам, но не изменять их атрибуты?

Ответы [ 2 ]

5 голосов
/ 15 марта 2011

Вы смешиваете JSF и CDI.Ваш UserSessionBean является JSF @ManagedBean, но вы используете CDI @Inject для внедрения его в другой компонент.CDI не использует JSF, управляемый JSF, а создает новый.Используйте один или другой, а не оба.Правильная аннотация для внедрения JSF-управляемого компонента: @ManagedProperty.

Замените

@Inject
private UserSessionBean userSessionBean; 

на

@ManagedProperty(value="#{userSessionBean}")
private UserSessionBean userSessionBean; 

и убедитесь, чтоу вас нет кода import javax.enterprise.context в вашем коде (который представляет собой пакет аннотаций CDI).

В качестве альтернативы перенесите все аннотации управления bean-компонентами JSF в аннотации управления bean-компонентами CDI.

import javax.inject.Named;
import javax.enterprise.context.SessionScoped;

@Named
@SessionScoped
public class UserSessionBean implements Serializable {}

import javax.inject.Named;
import javax.faces.view.ViewScoped;

@Named
@ViewScoped
public class ViewLines implements Serializable {}

Дополнительным преимуществом является то, что вы можете просто @Inject его внутри обычного сервлета или фильтра без необходимости вручную захватывать его как атрибут запроса / сеанса / приложения.

Более того, аннотации управления компонентами JSF устарели с момента выпуска JSF 2.3.См. Также Резервные бины (@ManagedBean) или CDI-бины (@Named)?

0 голосов
/ 14 марта 2011

Мой лучший догадка относительно того, почему это происходит, заключается в том, что файл переменной устанавливается в области видимости, а затем передается по ссылке в bean-объект области действия. Возможно, это происходит потому, что, когда компонент области видимости уничтожен, у него все еще есть ссылка на эту переменную, но он не заботится о том, чтобы найти какие-либо другие ссылки на него в области действия сеанса, где он должен быть сохранен. Следовательно, когда он уничтожается, в этом случае он удаляется из области просмотра и сеанса.

Не могли бы вы попробовать вызвать setCurrentFile с объектом, созданным с помощью 'new'? Это может доказать или опровергнуть мою гипотезу.

В противном случае мой лучший совет - открыть отладчик и посмотреть, где именно изменяется getCurrentFile.

...