Конструктор ViewScope вызывается дважды, не знаю почему - PullRequest
4 голосов
/ 04 февраля 2011

Я видел другие вопросы, касающиеся вызова конструктора bean-компонентов и ViewScope, и у меня все еще возникают трудности. Проблема, с которой я сталкиваюсь, связана с двумя конкретными страницами в моем приложении. Первая - это таблица данных (на данный момент она заполнена случайно сгенерированными данными, но в конечном итоге будет вызывать базу данных), вторая страница - довольно простая страница отображения, на которой информация из выбранной строки отображается в форме для редактирования или просмотра - это моя detail.xhtml страница. Это боб для этой страницы, которая является проблемой; его конструктор вызывается дважды: сначала, когда я перехожу на страницу, снова, когда я нажимаю кнопку command, не имеет значения, отправлять ли изменения или отменять изменения, конструктор вспомогательного компонента detail.xhtml вызывается во второй раз.

Мой боб @ViewScoped, импорт javax.faces.bean.ViewScoped. Несколько других деталей, которые могут иметь значение, но если они делают, я не понимаю, почему: мой UserDetailBean.java наследуется от базового компонента (который я так изначально называю UIBaseBean.java). Теперь мой UIBaseBean @RequestScoped. Как я понимаю, это не должно иметь никакого значения, потому что мой UserDetailBean @ViewScoped, пожалуйста, исправьте меня, если я ошибаюсь.

Другая деталь, которая может иметь значение, - это установка переменной в конструкторе как UIBaseBean, так и UserDetailBean. Я хочу отобразить местоположение пользователя на панели инструментов в верхней части моих страниц. Для этого я создал переменную в UIBaseBean:

protected String toolbarDescription;

Я также предоставил установщик и получатель в UIBaseBean. В конструкторе UIBaseBean я определяю переменную:

toolbarDescription = "fix me";

Это определение только для того, чтобы я знал, что нужно переопределить переменную в компоненте поддержки для любой конкретной страницы в моем приложении. В моем UserDetailBean я назначаю новое значение для String toolbarDescription. Это значение отображается на странице detail.xhtml. В противном случае bean-компонент для моей страницы detail.xhtml является очень простым, он получает и устанавливает свойства для отображения данных в форме на странице detail.xhtml.

Страница сведений настроена таким образом, что навигация по ней происходит с помощью перенаправления, а навигация в сторону (когда нажата кнопка command) происходит с перенаправлением. Я пытался использовать правила навигацииface-config с перенаправлениями и без них и неявную навигацию с перенаправлениями и без них, но конструктор UserDetailBean всегда вызывается дважды.

О, я установил точку останова для переменной toolbarDescription в моем конструкторе UserDetailBean, который дважды останавливает программу: при первом вызове страницы и снова после нажатия кнопки Command на странице сведений.

Из того, что я описал, кто-нибудь может сказать мне, почему мой конструктор вызывается дважды? Неправильно ли я спроектировал свой компонент или проблема в моем приложении?

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
import [package name].UIBaseBean;    
import java.util.Locale;
import javax.faces.bean.ManagedProperty;


@ManagedBean
@ViewScoped

public class UserDetailBean extends UIBaseBean {

@ManagedProperty(value = "#{param.action}")
private String action;

private String firstName;
private String lastName;
private String jobTitle;
private String DOH;
private String location;
private String status;
private String comments;
@ManagedProperty(value = "#{param.id}")
private String id;
private String tabTitle;

private boolean editMode;
private boolean viewMode;

private ClUserDetail dBUserDetail;      

    /** Creates a new instance of UserDetailBean */
    public UserDetailBean() {   
        toolbarDescription = CoreMsgBundle.getMessageFromResourceBundle("UserDetail", Locale.ENGLISH);
    }

1 Ответ

4 голосов
/ 04 февраля 2011

Вам необходимо удалить @RequestScoped и другие связанные аннотации из UIBaseBean (и сделать его abstract).

Как только это будет сделано, вам также нужно исправить @ManagedProperty на#{param} определяется либо <f:viewParam>, либо вместо ExternalContext#getRequestParameterMap().А именно, невозможно внедрить что-то с более короткой областью действия во что-то с большей областью действия (потому что неясно, какую из них следует вводить, поскольку их может быть больше в области действия акцептора).JSF сгенерирует исключение при создании бина.

...