JSF 2-Bean验证:验证失败->空值将替换为托管Bean中的最后一个有效值 [英] JSF 2 - Bean Validation: validation failed -> empty values are replaced with last valid values from managed bean

查看:82
本文介绍了JSF 2-Bean验证:验证失败->空值将替换为托管Bean中的最后一个有效值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我不了解评估期间JSF2的行为.希望可以有人帮帮我.


I do not understand the behaviour of JSF2 during valdation. Hope someone can help me.

我有一个表单,其中的字段在(ajax)提交后进行了验证-好的
如果验证失败,则会显示错误消息-确定

I have a form where the fields are validated after (ajax) submit - ok
If the validation failed a error message is shown - ok

以我的示例为例,当我输入有效的生日且字段 name 为空时,提交后会显示 name 的错误消息.
现在,当我输入有效的名称并从 birthday 字段中删除输入时,会显示 birthday 的错误消息(没关系),但是现在是旧的'valid' birthday 也位于输入字段中!?!

For my example when I enter a valid birthday and the field name is empty an errormessage for name is shown after submit.
Now when I enter a valid name and delete the input from the birthday field an errormessage is show for birthday (that's ok) but now the old 'valid' birthday stands also in the input field!?!

如何避免这种行为? 当我提交一个空字段时,我想看到一个错误消息和一个空字段...

How can I avoid this behaviour? When I submit an empty field I want to see an errormessage and an empty field...

这是我的示例代码:

我使用一个包含EntityBean( Contact )的ManagedBean( TestBean ). Contact 包含每个注解的验证.

I use a ManagedBean (TestBean) that contains an EntityBean (Contact). The Contact contains validations per annoations.

public class Contact implements Serializable {
    @NotNull 
    @Temporal(TemporalType.DATE)
    private Date birthday;

    @NotNull 
    @Size(min=3, max=15)
    private String name;

    //...
}

我的 ManagedBean :

@ManagedBean
@ViewScoped
public class TestBean implements Serializable {
    private Contact contact;

    @PostConstruct
    void init() {
        System.out.println("init...");
        contact = new Contact(); 
    }

    public void newContact(ActionEvent ae) {
        System.out.println("newContact...");
        contact = new Contact();
    }

    public void save() {
        System.out.println("save...");
        //TODO do something with contact...
    }

    public Contact getContact() { return contact; }

    public void setContact(Contact contact) {this.contact = contact;}
}

这是我的JSF页面:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core" >      
 <h:body>
    <h:form>     
        <h:panelGrid columns="3">   

        <h:outputText value="Birthday: " />  
        <h:inputText id="birthday" value="#{testBean.contact.birthday}">
            <f:convertDateTime/>
        </h:inputText>  
        <h:message for="birthday" />  

        <h:outputText value="Name: " />  
        <h:inputText id="name" value="#{testBean.contact.name}"/>
        <h:message for="name" />

        </h:panelGrid>  

        <h:commandButton value="submit" action="#{testBean.save}"> 
            <f:ajax execute="@form" render="@form"/>
        </h:commandButton> 

        <h:commandButton value="newContact" actionListener="#{testBean.newContact}"
                         immediate="true"> 
            <f:ajax render="@form"/>
        </h:commandButton> 

    </h:form>
</h:body>
</html>

最后是web.xml的片段

at last a snippet from web.xml

<context-param>
    <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
    <param-value>true</param-value>
</context-param>

<context-param>
    <param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
    <param-value>true</param-value>
</context-param>

感谢一些提示

推荐答案

您的特定问题是由

<context-param>
    <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
    <param-value>true</param-value>
</context-param>

和Mojarra的HtmlBasicRenderer#getCurrentValue()中的错误(至少是疏忽):

and a bug (at least, an oversight) in HtmlBasicRenderer#getCurrentValue() of Mojarra:

if (component instanceof UIInput) {
    Object submittedValue = ((UIInput) component).getSubmittedValue();
    if (submittedValue != null) {
        // value may not be a String...
        return submittedValue.toString();
    }
}

String currentValue = null;
Object currentObj = getValue(component);
if (currentObj != null) {
    currentValue = getFormattedValue(context, component, currentObj);
}
return currentValue;

通常,成功转换和验证UIInput组件时,将提交的值设置为null.当JSF将要重新显示值时,它将先检查提交的值是否不是null,然后再继续显示模型值.但是,使用此上下文参数时,它是null而不是无效的空字符串,因此当您删除必填字段的初始值时,它将始终重新显示原始模型值.

Normally, the submitted value is set to null when the UIInput component is successfully converted and validated. When JSF is about to redisplay the value, it first checks if the submitted value is not null before proceeding to redisplay the model value. However, with this context parameter, it is null instead of an empty string when it is invalid and thus it will always redisplay the original model value when you remove the initial value of a required field.

要对其进行测试,请将上下文参数值设置为false或将其完全删除.您会看到它按预期工作.但是,这将带来缺点,即模型值将在空的但不是必需的字段上被空字符串弄乱,并且您将失去使用JSR 303 bean验证的@NotNull注释的优势.

To test it, set that context param value to false or remove it altogether. You'll see that it works as intended. However, it will bring back the disadvantage that your model values will be cluttered with empty strings on empty but non-required fields and you'll lose the advantage of using @NotNull annotation of JSR 303 bean validation.

要解决此问题,您必须按如下所示更改HtmlBasicRenderer#getCurrentValue()的第一部分:

To fix this, you've to alter the first part of HtmlBasicRenderer#getCurrentValue() as follows:

if (component instanceof UIInput && !((UIInput) component).isValid()) {
    Object submittedValue = ((UIInput) component).getSubmittedValue();
    if (submittedValue != null) {
        // value may not be a String...
        return submittedValue.toString();
    } else {
        return null;
    }
}

我已经以 issue 2262 的形式向Mojarra的人报告了.

I've already reported it to Mojarra guys as issue 2262.

这篇关于JSF 2-Bean验证:验证失败->空值将替换为托管Bean中的最后一个有效值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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