8

我有一个布尔字段,我想验证它只有“true”或“false”作为值(不带引号)。但是这个字段也允许“真”或“假”作为我想要限制的值(带引号)。

我尝试使用 @Pattern 注释来匹配这些值。但我有以下错误:

javax.validation.UnexpectedTypeException:HV000030:找不到约束“javax.validation.constraints.Pattern”验证类型“java.lang.Boolean”的验证器。检查“可重新启动”的配置

我的代码是:

@Pattern(regexp = "^(true|false)$", message = "restartable field allowed input: true or false")
private Boolean restartable;

我应该怎么办?有没有其他方法可以克服这个问题?提前致谢。

4

4 回答 4

12

如果目标是强制执行非 null 和真值,则可以使用javax.validation 中存在的@NotNulland@AssertTrue或断言。@AssertFalse

https://docs.oracle.com/javaee/7/tutorial/bean-validation001.htm

@NotNull
@AssertTrue
private Boolean restartable;

如果值可以是 true 或 false,则 Not Null 注释就足够了,因为 Java 中的布尔值只能有两个值。

于 2019-05-30T15:40:22.883 回答
3

我在对布尔值进行表单验证时遇到了类似的问题,从技术上讲,我只希望客户端传递 true 或 false,没有其他值,以确保他们理解他们实际上是在传递这些值,而不是传递整数和我的代码基于 false 的解释值运行(Boolean.valueOf() 基本上对除 true 之外的任何内容都返回 false)。

为了澄清问题陈述,由于有些人看起来有点困惑,布尔验证在这里失败,因为它们可以通过

{...
"value":8675309,
...}

其中 value 应该是布尔值(但显然是作为 int 传递的),但是验证器/转换器只是在传入的对象上运行 Boolean.valueOf() ,在这种情况下会导致错误,这可能会导致下游逻辑和更改客户没有预料到(即,如果布尔值类似于keepInformation,则上述情况可能会导致用户丢失所有信息,因为表单未正确验证,并且您可能会因为客户没有而陷入困境' t “技术上”说“keepInformation”:假)

无论如何,为了解决这个问题,我发现最简单的方法是将布尔值存储为这样的字符串

    @NotNull
    @Pattern(regexp = "^true$|^false$", message = "allowed input: true or false")
    private String booleanField;

我已经测试过这个正则表达式,它只会传递“value”:true/“true”或“value”:false/“false”,它会因额外的引号而失败(“value”:“\”true\” ")、空格 ("value":"true") 以及其他任何与我上面所说的不匹配的内容。

然后在该数据对象中您自己的 getter 中,您可以自己运行布尔转换以供下游使用。

    public boolean isSomething() {
        return Boolean.valueOf(booleanField);
    }
于 2020-07-23T17:40:32.513 回答
1

为什么要在布尔字段上使用文本验证?这就是错误所说的。

我认为检查它是否为空(使用@NotNull)会更有意义;如果它是非空的,那么它肯定是一个有效的布尔值,根据定义,它不能有任何其他值,除了真或假。另一方面,如果它为空,那么这可能就是您要检测的错误。

于 2019-05-30T15:34:55.867 回答
0

如果你只想知道哪个字段验证失败,可以设置一个 GlobalExceptionHandler 来捕获 ServerWebInputException,然后从 ServerWebInputException 中获取 rootcause instanceof InvalidFormatException,这个异常包含验证失败的字段信息和人类可读的原因。

于 2021-09-01T03:56:37.753 回答