JSF 2 - Bean验证:验证失败 - >空值被替换为来自托管bean的最后有效值

Mat*_*ing 11 java validation jsf-2


我不理解在valration期间JSF2的行为.希望可以有人帮帮我.

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

对于我的例子,当我输入有效的生日并且字段名称为空时,提交后会显示名称的错误消息.
现在,当我输入一个有效的名字并从生日字段中删除输入时,将显示生日错误消息(没关系),但现在旧的"有效" 生日也会出现在输入字段中!?!

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

这是我的示例代码:

我使用包含EntityBean(Contact)的ManagedBean(TestBean).该联系人包含每个annoations验证.

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

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

    //...
}
Run Code Online (Sandbox Code Playgroud)

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

这是我的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>
Run Code Online (Sandbox Code Playgroud)

最后一个来自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>
Run Code Online (Sandbox Code Playgroud)

谢谢你的一些提示

Bal*_*usC 8

你的特殊问题是由

<context-param>
    <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
    <param-value>true</param-value>
</context-param>
Run Code Online (Sandbox Code Playgroud)

HtmlBasicRenderer#getCurrentValue()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;
Run Code Online (Sandbox Code Playgroud)

通常情况下,所提交的值被设置为null当所述UIInput组件被成功地转换和验证.当JSF即将重新显示该值时,它首先检查提交的值是否null在继续重新显示模型值之前.但是,使用此上下文参数null时,它在无效时代替空字符串,因此在删除必填字段的初始值时,它将始终重新显示原始模型值.

要测试它,请将该上下文参数值设置为false或完全删除它.你会发现它按预期工作.但是,它会带来一个缺点,即您的模型值将在空的但非必需的字段上用空字符串混乱,并且您将失去使用@NotNullJSR 303 bean验证注释的优势.

要解决这个问题,你需要改变第一部分,HtmlBasicRenderer#getCurrentValue()如下所示:

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

我已经向Mojarra家伙报告了问题2262.

  • @BalusC:谢谢你的详细解释!你在这里的解决方案/解释经常使我的一天;-) (2认同)