Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to validate type 'java.lang.Boolean' in Spring boot

I have a boolean field which I want to validate to have only "true" or "false" as value(without quotes). But this field is also allowing "true" or "false" as value(with quotes) which I want to restrict.

I tried to use @Pattern annotation to match these values. But I have the following error:

javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'javax.validation.constraints.Pattern' validating type 'java.lang.Boolean'. Check configuration for 'restartable'

My code is:

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

What should i do? Is there some other way to overcome this issue? Thanks in advance.

like image 397
Nobita Avatar asked May 30 '19 15:05

Nobita


People also ask

How do you validate a boolean value in Java?

parseBoolean(String s) − This method accepts a String variable and returns boolean. If the given string value is "true" (irrespective of its case) this method returns true else, if it is null or, false or, any other value it returns false.

How do you validate fields in Spring Boot?

Validation in Spring Boot is done mainly by using Hibernate Validator — an implementation of Java Bean Validation using annotation based constraints. But while Hibernate provides a powerful set of constraint violations checkers out of the box, we'll need to put some effort into handling the exceptions it throws.

What is @valid annotation in Spring Boot?

The @Valid annotation ensures the validation of the whole object. Importantly, it performs the validation of the whole object graph. However, this creates issues for scenarios needing only partial validation. On the other hand, we can use @Validated for group validation, including the above partial validation.


3 Answers

you can use @NotNull and @AssertTrue or @AssertFalse assertions present in javax.validation if the goal is to enforce non null and truthy value.

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

@NotNull
@AssertTrue
private Boolean restartable;

Not Null annotation would suffice if the value can be either true or false as booleans in Java can only have two values.

like image 163
Technoshaft Avatar answered Sep 16 '22 13:09

Technoshaft


I had a similar issue with form validation of a Boolean value, where I technically only wanted the client to pass either true or false, no other values, to ensure they understood they were actually passing those values, and not passing an integer and my code running based on the interpretted value of false (Boolean.valueOf() returns false for basically anything besides true).

To clarify the problem statement, since some people seem a little confused, boolean validation fails here because they can pass

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

where value is SUPPOSED to be boolean (but clearly passed as int), however the validator/converter just runs Boolean.valueOf() on the passed in object, which in this case would result in false, which could result in downstream logic and changes that the client was NOT expecting (ie if boolean value was something like keepInformation, that above scenario could result in a user losing all of their information because the form wasn't correctly validated, and you possibly being on the hook since the client didn't "technically" say "keepInformation":false)

Anyways, in order to combat this, I found the easiest way was to store the boolean as a String like such

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

I've tested this regex and it will ONLY pass for "value":true/"true", or "value":false/"false", it will fail on extra quotes ("value":"\"true\""), whitespace ("value":"true "), and anything else that doesn't match what I put above.

Then in your own getter in that data object you can run the boolean conversion yourself for downstream use.

    public boolean isSomething() {
        return Boolean.valueOf(booleanField);
    }
like image 45
Logan Smith Avatar answered Sep 20 '22 13:09

Logan Smith


Why are you using a text validation on a boolean field? that's what the error is stating.

I think it would make more sense to check if it's null or not (use @NotNull); if it's non-null then surely it's a valid boolean, by definition it can't have any other value besides true or false. On the other hand, if it's null then that's probably the error that you want to detect.

like image 29
Óscar López Avatar answered Sep 18 '22 13:09

Óscar López