JSF 2.0:как пропустить проверку JSR-303 bean?

как пропустить проверку JSR-303 Bean с помощью JSF, когда нажата кнопка?

немного длинный вопрос, чтобы объяснить несколько подходов... Рассмотрим список в виде:

<h:form id="form">
    <h:commandButton value="Add row">
        <f:ajax execute="foo" listener="#{bean.add()}" render="foo" />
    </h:commandButton>
    <h:dataTable id="foo" var="foo" value="#{bean.foos}">
        <h:column>
            Name: <h:inputText id="field" value="#{foo.name}" required="true" />
            <h:messages for="field" />
        </h:column>
        <h:column>
            <h:commandButton value="Remove">
                <f:ajax execute=":form:foo" listener="#{bean.remove(foo)}" render=":form:foo" />
            </h:commandButton>
        </h:column>
    </h:dataTable>
</h:form>

когда пользователь нажимает кнопку Добавить или удалить строку, действие должно выполняться без проверки. Проблема в том, что JSF повторно отображает весь список и пытается его проверить. Если есть черновики изменений, которые не проверяются, возникают ошибки проверки и метод прослушивателя никогда не вызывается (как неудачная проверка помешать этому.) Однако, добавив immediate="true" в f: ajax позволяет методу выполняться, несмотря на ошибки проверки. Однако ошибки проверки по-прежнему происходят и показаны здесь.

Я вижу два варианта:

1) Используйте immediate= "true" и не показывайте ошибки проверки

для неподтверждающих кнопок установите immediate= "true" и для H:сообщения do:

<h:messages rendered="#{param['SHOW_VALIDATION']}" />

затем установите Save-button (которая должна фактически попытаться сохранить форму), чтобы отправить это параметр:

<h:commandButton>
    <f:param name="SHOW_VALIDATION" value="true" />
</h:commandButton>

это вызывает проверку, но сообщения просто не отображаются, за исключением случаев, когда

4 ответов


установите обработчики событий как immediate=true и звонок FacesContext.renderResponse() прежде чем выйти из них.

обновление:

изменения в вашей форме примера:

<h:form id="form">
    <h:commandButton value="Add row">
        <!-- Added immediate="true" to call bean.add() before validation phase -->
        <f:ajax execute="foo" listener="#{bean.add()}" render="foo" immediate="true"/>
    </h:commandButton>
    <h:dataTable id="foo" var="foo" value="#{bean.foos}">
        <h:column>
            Name: <h:inputText id="field" value="#{foo.name}" required="true" />
            <h:messages for="field" />
        </h:column>
        <h:column>
            <h:commandButton value="Remove">
                <!-- Added immediate="true" to call bean.remove() before validation phase -->
                <f:ajax execute=":form:foo" listener="#{bean.remove(foo)}" render=":form:foo" immediate="true"/>
            </h:commandButton>
        </h:column>
    </h:dataTable>
</h:form>

изменения в вашем коде bean:

...
public void add() {
    // Your add() code
    ...
    // Added FacesContext.renderResponse() call to skip to render response phase
    FacesContext.getCurrentInstance().renderResponse();
}
...
public void remove() {
    // Your remove() code
    ...
    // Added FacesContext.renderResponse() call to skip to render response phase
    FacesContext.getCurrentInstance().renderResponse();
}
...

вы можете отключить проверку bean с тегом f: validateBean С атрибутом отключен.

пример:

<h:inputText value="#{bean.name}">
   <f:validateBean disabled="#{anotherBean.flag}"/>
</h:inputText>

мы только что опубликовали решение этой проблемы. Полная информация здесь: http://www.springfuse.com/2011/12/15/skip-jsf-validation-depending-on-action.html

короче говоря, он использует атрибут привязки тега validateBean. Это позволит вам перехватить метод validate и решить, на основе нажатой кнопки, пропустить его или нет.


ситуация: В коде страницы есть большая форма с множеством полей ввода. Есть несколько кнопок, каждая из которых указывает на отдельное действие в отдельном Бобе.

решение, которое сработало для меня...

  1. в коде страницы: добавить immediate="true" к кнопке и укажите идентификатор полей ввода,которые вы хотите использовать в компоненте.
 <p:inputText id="someHtmlInputId"
               maxlength="30" 
               value="#{beanName.attr}" />


 <p:commandButton id="someHtmlButtonId"
                   actionListener="#{beanName.doStuff}" 
                   value="Button Label"
                   ajax="false"
                   immediate="true"/>
  1. в зернах doStuff метод получает параметры по фрагменту имени couse перед именем ввода JSF помещает некоторые другие идентификаторы, и результирующее имя параметра может выглядеть так:someFormId:j_idt54: someHtmlInputId
Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
if (params != null) {
  for (String k: params.keySet())
      if (k.indexOf("someHtmlInputId") != -1)
          params.get(k); // This is Your input parameter value waiting to be processed ;)
}