Значение JSF selectOneMenu не установлено

У меня есть страница, на которой отображается SelectOneMenu независимо от того, есть ли какая-то информация о БД или нет. Моя форма выглядит так:

...
<h:form id="wrapperUpload" enctype="multipart/form-data" >
<h:outputLabel for="option" value="Tipo de carga: "
                            rendered="#{uploadFile.check(userVerifier.dependencia)}" />
<h:selectOneMenu id="option"
                 value="#{uploadFile.optionSelected}"
                 rendered="#{uploadFile.check(userVerifier.dependencia)}"  >
    <f:selectItems value="#{uploadFile.options}" />
</h:selectOneMenu>
<h:outputLabel for="upfile" value="Archivo: " />
<t:inputFileUpload id="upfile" required="true" 
                   value="#{uploadFile.upFile}" />
<h:commandButton value="Validar #{userVerifier.dependencia}"
                 action="#{uploadFile.upload}"
                 onclick="return confirmation()" >
    <f:param name="dependencia" value="#{userVerifier.dependencia}" />
</h:commandButton>
</h:form>
...

И моя фасоль

private UploadedFile upFile;
private boolean showOptions = false;
private final String[] options = {
    "Seleccione una opción.",
    "Cargar toda la información.",
    "Cargar solo información errónea."
};
private String optionSelected;
private Database db = new Database();

public UploadedFile getUpFile() {
    return upFile;
}

public void setUpFile(UploadedFile upFile) {
    this.upFile = upFile;
}

public String[] getOptions() {
    return options;
}

public void setOptionSelected(String optionSelected) {
    this.optionSelected = optionSelected;
}

public String getOptionSelected() {
    return optionSelected;
}

public boolean check(String dependencia) {
    String hasInfo;
    hasInfo = db.checkForInfo(dependencia);
    if (hasInfo.equals("T")) {
        showOptions = true;
    } else {
        showOptions = false;
    }
    return showOptions;
}

public String upload() {
    byte[] buffer = null;
    int count = 0;
    File serverFile = null;
    InputStream input = null;
    OutputStream output = null;

    Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
    String dependencia = params.get("dependencia");
    String extension = FilenameUtils.getExtension(upFile.getName());

    System.out.println("__depend:   " + dependencia);
    System.out.println("__option:   " + optionSelected);  //null
...
...

Наконец, когда я нажимаю кнопку, значение SelectOneMenu (или selectedOption в моем компоненте) всегда равно нулю... Как это исправить? Я что-то упускаю?

Забыл упомянуть, что если я удалю часть рендеринга, все будет работать нормально...


person BRabbit27    schedule 03.11.2011    source источник
comment
Это не настоящий код. У вас нет метода isCheck() и вы не используете rendered="#{uploadFile.check('somestring')}". Это уже вызовет исключение EL при отображении формы. Пожалуйста, покажите реальный код.   -  person BalusC    schedule 03.11.2011
comment
Извините, что говорю вам, но да, это настоящий код, я пропустил остальную часть кода, но в основном это то, что у меня есть... Но я опубликую весь код, так что, возможно, вы сможете помочь.   -  person BRabbit27    schedule 03.11.2011
comment
rendered="#{uploadFile.check}" ожидает метод public boolean isCheck(), а не метод public boolean check(String dependencies). Это должно было вызвать исключение EL. Какой контейнер вы используете?   -  person BalusC    schedule 03.11.2011
comment
Вот оно, надеюсь, что поможет лучше. Извините, если я публикую неполный код. О, я понимаю, что вы имеете в виду... Я попытаюсь это исправить... но он не отправляет никаких исключений EL, но для хорошей практики я изменю его.   -  person BRabbit27    schedule 03.11.2011
comment
Теперь, когда вы изменили его на rendered="#{uploadFile.check(userVerifier.dependencia)}", он выглядит лучше. Изначально у вас было rendered="#{uploadFile.check}", что недопустимо в сочетании с данным методом.   -  person BalusC    schedule 03.11.2011


Ответы (1)


Забыл упомянуть, что если я удалю часть визуализации, все будет работать нормально

Это может означать только то, что bean-компонент находится в области запроса и что атрибут rendered зависит от переменной на основе запроса, которая присутствовала в первоначальном запросе при отображении формы, но отсутствует в последующем запросе при обработке отправки формы.

Помещение bean-компонента в область представления или обеспечение сохранения переменной на основе запроса в последующем запросе должно решить вашу проблему.

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

Смотрите также:


Обновление: в соответствии с вашим обновлением и комментариями вы должны сделать UserVerifier управляемым свойством компонента UploadFile и выполнить предварительную инициализацию в конструкторе (post). Что-то типа:

@ManagedBean
@ViewScoped
public class UploadFile {

    @ManagedProperty("#{userVerifier}")
    private UserVerifier userVerifier; // +setter

    private boolean showOptions;

    @PostConstruct
    public void init() {
        showOptions = "T".equals(db.checkForInfo(userVerifier.getDependencia()));
    }

    public boolean isShowOptions() {
        return showOptions;
    }

    // ...
}

с участием

rendered="#{uploadFile.showOptions}"

и избавиться от <f:param>.

person BalusC    schedule 03.11.2011
comment
Как я могу сохранить эту переменную? Я поместил его в View Scope, но это породило новую проблему: теги <f:param> и <t:inputFileUpload value> больше не сохраняют значение. Я положил его на <h:inputText>, чтобы увидеть, есть ли у них ценность, и они есть. - person BRabbit27; 04.11.2011
comment
Инициализируйте свойство в конструкции bean (post) и просто не используйте f: param. Бин с областью видимости живет до тех пор, пока вы взаимодействуете с одним и тем же представлением. Свойство будет иметь то же значение при последующих обратных передачах. Вам не нужно передавать его вперед и назад через HTTP-запросы. - person BalusC; 04.11.2011
comment
Я не понимаю ... Я новичок в JSF, поэтому, если бы вы могли объяснить мне подробно. Должен ли я инициализировать bean-компонент userVerifier? Идея такова: после входа в систему (после проверки правильности пароля пользователя) на этой странице я проверю БД, чтобы увидеть, есть ли у пользователя уже данные, и если они есть, отобразить selectOneMenu. Затем, после выбора файла и нажатия кнопки, он должен проверить, выбрал ли пользователь допустимую опцию из selectOneMenu, и выполнить загрузку. - person BRabbit27; 05.11.2011
comment
Есть здесь кто-нибудь? Можете ли вы объяснить мне подробно? - person BRabbit27; 07.11.2011
comment
Благодарность ! Сразу проверю и отпишусь о результатах! Кстати, где я могу узнать все это? Это какой-то продвинутый материал JSF? - person BRabbit27; 07.11.2011
comment
Я вернулся... Я попробую, и возникло следующее исключение javax.servlet.ServletException: No se puede crear el bean administrado uploadFile. Se han encontrado los problemas siguientes: - El ámbito del objeto al que hace referencia la expresión #{userVerifier}, request, es más corto que el ámbito de view del bean administrado de referencia (uploadFile) у bean-компонента UserVerifier есть RequestScoped, но для того, что говорит исключение, я думаю, что оно также должно быть ViewScoped? - person BRabbit27; 08.11.2011
comment
Я понял, что UserVerifier представляет текущего пользователя, вошедшего в систему/активного, и я ожидаю, что он будет в области сеанса. Что именно представляет этот компонент и почему именно он находится в области запроса? - person BalusC; 08.11.2011
comment
Ну, я поместил его в SessionScoped, и эта часть работает нормально, но после того, как я загрузил файл, у меня есть третья (и последняя) страница, на которой я хотел отобразить имя загруженного файла. Поскольку UploadFile теперь ViewScoped (поправьте меня, если я ошибаюсь), когда я перехожу на следующую страницу, bean-компонент теряется. Я имею в виду сделать что-то похожее на то, что мы сделали с UserVerifier. Это хорошая идея? Кстати, есть ли лучший способ передать информацию с одной страницы на другую в JSF? как и в моем проекте, page1:getsUser -> page2: использует этого пользователя для проверки БД и uploadFile -> page3: использует имя uploadFile. БЛАГОДАРНОСТЬ ! - person BRabbit27; 08.11.2011
comment
Компонент с областью видимости существует, пока вы взаимодействуете с одним и тем же представлением. Я понятия не имею, почему вы хотите, чтобы этот компонент был на следующей странице, чтобы отображать результаты? Почему бы вам просто не сделать это в том же виде? Что касается областей действия bean-компонентов и всего прочего, что касается связи в JSF, вам может быть полезна эта статья: balusc.blogspot.com/2011/09/communication-in-jsf-20.html - person BalusC; 08.11.2011
comment
Да, после загрузки файла на следующей странице будет просто сообщение типа Мы получили файл: Blabla.txt Это то, что хочет клиент, но если ваш совет и рекомендации говорят о том, что было бы лучше есть на той же странице (представление) я изменю. Я прочитаю статью и продолжу изучение этой интересной (и довольно редкой для меня) технологии, ха-ха. Еще раз спасибо. - person BRabbit27; 08.11.2011