Bean Validation @NotNull、@NotBlank 和 @NotEmpty 在 JSF+Tomcat 中不起作用

Posted

技术标签:

【中文标题】Bean Validation @NotNull、@NotBlank 和 @NotEmpty 在 JSF+Tomcat 中不起作用【英文标题】:Bean Validation @NotNull, @NotBlank and @NotEmpty does not work in JSF+Tomcat 【发布时间】:2011-11-24 14:31:26 【问题描述】:

我在我的 JSF 托管 bean 中使用 Hibernate Validation 注释。当我使用@NotNull@NotBlank@NotEmpty 时,它们似乎不会以任何方式被触发。

@NotBlank(message = "name.required")
public String name;

查看:

<h:outputLabel value="Name:" /> 
<h:inputText id="name" value="#person.name" size="20" />
<h:message for="name" style="color:red" />

这是怎么引起的,我该如何解决?

【问题讨论】:

你用的是什么容器? 【参考方案1】:

简介

由于您没有就您正在使用的容器问题对我的评论提供任何反馈,因此我查看了您的问题历史以了解您都在使用哪些容器。到目前为止,我只找到了Tomcat。因此,对于这个答案,我假设您确实在使用 Tomcat,正如我在发布评论时最初猜测的那样。

确保安装所有 JAR

Tomcat 不附带任何开箱即用的 JSR303 Bean 验证 API/实现。你需要自己download and install。您获得了要编译的注释意味着您已将 hibernate-validator.jar 文件(每个版本的命名可能不同)正确地放置在 webapp 的 /WEB-INF/lib 文件夹中。反过来,这些注释似乎无法以任何方式工作,这仅意味着您没有阅读 readme.txt 和/或忘记从 Hibernate Validator 库 zip/tgz 文件的 /lib/required 文件夹中添加 JAR: slf4j-api.jarvalidation-api.jar。最后一个是强制性的,以使注释真正起作用。因此,要让 Hibernate Validator 在 Tomcat 中工作,您需要在 webapp 的 /WEB-INF/lib 中提供以下 JAR:

validation-api.jar(包含抽象 API 和注释扫描器) hibernate-validator.jar(包含具体实现) slf4j-api.jar(只是为了让它的记录器也能正常工作)

这种方式@NotBlank@NotEmpty 必须工作。 @NotNull 值得特别关注;由于 HTTP 请求参数的性质,空输入字段默认情况下作为空字符串从客户端(网络浏览器)接收。空字符串与null 不同,因此默认情况下@NotNull 不会启动。但是,JSF 可以配置为将它们解释为null,只需将以下上下文参数添加到web.xml

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

这样@NotNull 也必须工作。

BV 有效,但只有空字段无效

如果它仍然不起作用(即 3 个注释都不起作用,但其他注释(例如 @Size(min=5) 至少 5 个)可以正常工作),那么您很有可能已经web.xml 中还有以下上下文参数:

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

然后您应该删除它(它默认为 auto,即仅当在运行时类路径中找到 JSR303 Bean Validation API 时)或将其设置为 true

BV 根本不起作用

如果 BV 实际上没有任何作用,@Size@Pattern 等也不起作用,那么您应该验证您是否在您的表单中包含以下内容:

<f:validateBean disabled="true" />

然后您应该删除它(默认情况下它会启动)或设置disabled="false"

确保您使用的是最新的 Mojarra

当 BV 仍然 不起作用时,请验证您是否使用的是 2.2.3 和 2.2.6 之间的旧 Mojarra 版本。这些版本有一个类加载委托错误,导致 Tomcat 上的 Bean Validation 和克隆完全不可见。这被报告为 Mojarra issue 3183 并在 Mojarra 2.2.7 中修复。

【讨论】:

嗨 BalusC,对不起,我没有看到您对我的帖子的评论,但现在,非常感谢您的详细解释,问题是我遇到了: javax.faces.VALIDATE_EMPTY_FIELDSfalse 我没有看到,我只是使用了在线示例中的 web.xml,我我是 jsf 的新手,非常感谢。 @BalusC,我拥有所有必需的依赖项,并且在同一个(字符串)字段上@NotEmpty 被调用并按预期工作,但@NotBlank 被忽略。如果使用 @NotBlank 注释,即使对于 null 和空字符串也不会产生任何错误。您知道可能导致问题的原因吗? 就像破案一样。 “由于您没有就您使用的容器问题对我的评论提供任何反馈,因此我查看了您的问题历史记录以了解您都在使用哪些容器。到目前为止,我只找到了 Tomcat。因此,对于这个答案,我假设您确实在使用 Tomcat,正如我在发布评论时最初猜测的那样。哇...只是...哇... 我无法访问我的所有验证消息。同一个超类中的@NotEmpty 进展顺利,而@NotNull 仅显示默认消息。 @BalusC 或任何人有想法?【参考方案2】:

我有一个类似的问题,我能够通过在web-inf lib 中包含以下三个 jar 来克服这个问题。只需添加 zip 文件中提供的休眠验证器 jar 和所需的 jar:

hibernate-validator-4.3.0.Final.jar jboss-logging-3.1.0.CR2.jar validation-api-1.0.0.GA.jar

【讨论】:

【参考方案3】:

如果添加上述jars后仍然无法验证,那么您可能错过了添加标签

 <mvc:annotation-driven />

在spring配置文件中。

【讨论】:

这仅适用于您使用 Spring 而不是 Java EE。

以上是关于Bean Validation @NotNull、@NotBlank 和 @NotEmpty 在 JSF+Tomcat 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

javax.validation - BindingResult

Java bean validation 规范与参考实现

Spring整合Bean Validation

javax.validation.NoProviderFoundException:无法创建配置,因为找不到 Bean 验证提供程序

Bean Validation原理篇--07

Bean Validation核心组件篇----04