JSF 2.0:如何跳过JSR-303 bean验证?

Tuu*_*nen 12 jsf facelets bean-validation jsf-2

当点击一个按钮时,如何跳过使用JSF的JSR-303 Bean验证?

解释一些方法有点冗长的问题......考虑一个表单中的列表:

<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>
Run Code Online (Sandbox Code Playgroud)

当用户单击添加或删除行时,操作应该在没有验证的情况下执行.问题是,JSF重新呈现整个列表并尝试验证它.如果存在未验证的草稿更改,则会发生验证错误,并且永远不会调用侦听器方法(因为验证失败会阻止该操作).但是,添加immediate="true"到f:ajax允许方法执行,尽管有验证错误.但是,验证错误仍然会发生并显示在此处.

我看到两个选择:

1)使用immediate ="true"并且不显示验证错误

对于非验证按钮,设置immediate ="true"和h:消息:

<h:messages rendered="#{param['SHOW_VALIDATION']}" />
Run Code Online (Sandbox Code Playgroud)

然后设置保存按钮(实际上应该尝试保存表单)以发送该参数:

<h:commandButton>
    <f:param name="SHOW_VALIDATION" value="true" />
</h:commandButton>
Run Code Online (Sandbox Code Playgroud)

这会导致验证,但除非SHOW_VALIDATION存在参数,否则不会显示消息.

2)有条件地在facelets中声明验证:

<h:inputText>
    <f:validateRequired disabled="#{!param['VALIDATE']}" />
</h:inputText>
Run Code Online (Sandbox Code Playgroud)

并保存按钮:

<h:commandButton>
    <f:param name="VALIDATE" value="true" />
</h:commandButton>
Run Code Online (Sandbox Code Playgroud)

这会导致字段仅在VALIDATE参数存在时进行验证(=按下保存按钮时).

但这些似乎都是一种黑客攻击.我怎样才能简单地使用JSR-303 Bean验证,但在声明时跳过它?

gpe*_*che 9

将事件处理程序设置为immediate=trueFacesContext.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>
Run Code Online (Sandbox Code Playgroud)

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();
}
...
Run Code Online (Sandbox Code Playgroud)


vic*_*era 8

您可以禁用与标签Bean验证F:validateBean有一个属性禁用.

例:

<h:inputText value="#{bean.name}">
   <f:validateBean disabled="#{anotherBean.flag}"/>
</h:inputText>
Run Code Online (Sandbox Code Playgroud)

  • 您也可以用`f:validateBean`包装多个输入组件,如下所示:http://stackoverflow.com/a/17503608/1725096 (2认同)