Почему required=true не срабатывает при рендеринге=false

У меня есть некоторые сомнения по поводу разбора html-тегов в Facelet. Пусть у нас есть фейслет, который содержит следующее

<h:inputText id="username"
             title="My name is: "
             value="#{hello.name}"
             required="true"
             requiredMessage="Error: A name is required."
             rendered="false"
             maxlength="25" />
<h:commandButton id="submit" value="Submit" action="response">
            </h:commandButton>

После нажатия кнопки «Отправить» у меня нет Error: A name is required. Почему? username просто не отображается, и после submit клика в username нет значения.


person Community    schedule 18.11.2013    source источник
comment
Какую версию JSF и реализацию вы используете?   -  person Luiggi Mendoza    schedule 18.11.2013
comment
@Luiggi: поведение соответствует спецификации JSF, поэтому маловероятно, что проблема связана с внедрением / версией.   -  person BalusC    schedule 18.11.2013
comment
@BalusC Я неправильно понял я не на я , поэтому нашел это поведение действительно странным.   -  person Luiggi Mendoza    schedule 18.11.2013
comment
@Luiggi: ах, я определенно могу себе это представить, мне также пришлось дважды прочитать вопрос.   -  person BalusC    schedule 18.11.2013


Ответы (1)


Атрибут rendered также оценивается на этапах проверки и обновления значений модели. Для подтверждения проверьте javax.faces.component.UIInput исходный код (номера строк соответствуют Mojarra 2.2.0):

696     public void processValidators(FacesContext context) {
697 
698         if (context == null) {
699             throw new NullPointerException();
700         }
701 
702         // Skip processing if our rendered flag is false
703         if (!isRendered()) {
704             return;
705         }
...
...
...
735     public void processUpdates(FacesContext context) {
736 
737         if (context == null) {
738             throw new NullPointerException();
739         }
740 
741         // Skip processing if our rendered flag is false
742         if (!isRendered()) {
743             return;
744         }

Объяснение простое: это защита от фальсифицированных (поддельных/взломанных) HTTP-запросов, когда конечные пользователи целенаправленно манипулируют HTTP-запросом, пытаясь установить значения и/или вызвать действия скрытых входов/команд, которые им, скорее всего, просто не разрешены. обновить или вызвать, например кнопку удаления, которая отображается только в том случае, если у пользователя есть роль администратора:

<h:commandButton value="Delete" ... rendered="#{request.isUserInRole('ADMIN')}" />

Примечание: таким же образом обрабатываются атрибуты компонента readonly и disabled. Вместо этого для вашей конкретной цели используйте CSS display: none.

<h:inputText ... style="display:none" />

(примечание: это начальный пример, использование атрибута style является плохой практикой с точки зрения HTML/CSS, предпочтительнее styleClass с конкретным файлом CSS)

Хотя мне интересно, какие конкретные функциональные требования стоят за этим, это плохо для UX. Возможно, вы просто случайно экспериментировали, не изучив сначала спецификацию JSF, не говоря уже о исходный код JSF?

person BalusC    schedule 18.11.2013