JSF 2.0:如何跳过 JSR-303 bean 验证? [英] JSF 2.0: How to skip JSR-303 bean validation?

查看:34
本文介绍了JSF 2.0:如何跳过 JSR-303 bean 验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在单击按钮时使用 JSF 跳过 JSR-303 Bean 验证?

How to skip JSR-303 Bean validation with JSF, when a button is clicked?

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

A bit lengthy question to explain a few approaches... Consider a list in a form:

<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 允许方法执行,尽管验证错误.但是,验证错误仍然发生并显示在此处.

When user clicks add or remove row, the action should execute without validation. The problem is, JSF re-renders the whole list and tries to validate it. If there are draft changes that don't validate, validation errors occur and the listener method is never called (as failed validation prevents that). However, adding immediate="true" into f:ajax allows method to execute despite of validation errors. However, validation errors still occur and are shown here.

我看到两个选项:

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

1) Use immediate="true" and do not show validation errors

对于非验证按钮,设置immediate="true" 并为h:messages 设置:

For non-validating buttons, set immediate="true" and for h:messages do:

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

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

Then set Save-button (that should actually try to save the form) to send that parameter:

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

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

This causes validation occur, but messages are simply not shown except when SHOW_VALIDATION parameter is present.

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

2) Declare validation in facelets conditionally:

<h:inputText>
    <f:validateRequired disabled="#{!param['VALIDATE']}" />
</h:inputText>

和保存按钮:

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

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

This causes fields to validate only when the VALIDATE parameter is present (=when the Save-button has been pressed).

但这些看起来有点像黑客.如何简单地使用 JSR-303 Bean 验证但在声明时跳过它?

But these seem sort of a hacks. How can I simply use JSR-303 Bean Validation but skip it when declared?

推荐答案

将您的事件处理程序设置为 immediate=true 并在退出它们之前调用 FacesContext.renderResponse().

Set your event handlers as immediate=true and call FacesContext.renderResponse() before exiting them.

更新:

示例表单中的修改:

<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 代码:

Modifications in your bean code:

...
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();
}
...

这篇关于JSF 2.0:如何跳过 JSR-303 bean 验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆