当前位置: 首页 > 面试题库 >

JSF 2-Bean验证:验证失败->空值被托管Bean中的最后一个有效值替换

潘兴朝
2023-03-14
问题内容

我不了解评估期间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;

    //...
}

我的 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的片段

<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>

以及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;

通常情况下,所提交的值被设置为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;
    }
}

我已经把它报告给Mojarra了,发行号为2262。



 类似资料:
  • 我使用Spring 3.2.2与Primeface 4.0和Hibernate 4.2。我在我的实体上有JSR303验证注释,并且我配置了Spring来在服务层验证它们——这很好。 但是我希望在调用服务之前启动JSF验证,但事实并非如此。我所做的所有研究都表明,我只需在类路径中添加一个验证程序,JSF2就会自动应用。 我已将建议的JAR添加到我的类路径中: 完整的依赖关系树可以在https://g

  • 我知道这在这个论坛上不是新问题,但我很困惑我该怎么做。 问题:我正在用spring mvc+Hibernate开发一个应用程序。对于服务器端验证,我在controller中使用@valid注释,在bean中使用@null和@notnull注释。 例如: 这个验证很好地进行,数据也保存在DB中。 但我想验证唯一约束,引用完整性和其他约束使用注释没有任何验证器类。 有可能吗?如果没有,那么什么是最好和

  • 我的问题类似于不调用Resteasy Bean验证。不过,那里的解决方案并不奏效。 我使用的是Restease3.0.9。最终与resteasy-validator提供者-11在我的pom。我正在使用一个定制的码头类启动整件事。 奇怪的是,验证在@PathParams上运行良好,但在bean上却不行。 在这种情况下,myParam上的@Size约束可以正常工作。但是MyBean中的@NotNull

  • 因此,我正在对其执行JSR-303 bean验证的类有两个字段,每个字段都应用了相同的模式约束: 重要信息-此类不是经典Spring MVC webapp中的表单支持类,而是位于web服务基础上的实体类。因此,验证正在服务中进行。 现在,使用web服务的web客户端是一个Spring MVC,它有一个表单支持bean,该bean与jsp绑定,并带有放置错误消息的位置。 因此,假设用户在这两个字段中

  • 我有一个托管bean,它有以下方法: 因此,方法将打开一个对话框,并传递给它两个参数(和)。 然后命令按钮将从调用方法: 但我在行中得到了一个NullPointerException: 所以我在这一行上附加了一个dubugger,我得到了这个: 您可以注意到,变量具有空值,而具有字符串值。

  • 使用krasa-jaxb-tools jaxb-plugin,我生成了以下内容: 来自XSD架构: 我得到了注释元素: 使用JAXB,我成功地生成了有效的XML(它通过了XSD验证--包括上面提到的字符串的格式)。 但是,如果我尝试使用Bean验证验证上面提到的字符串,它会抛出错误--如果它被写为“small123”,它会说它应该大写(失败small.123[a-za-z0-9.]{0,27}re