Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javax.Validation - allow null but validate if the value is not

I am using javax Validation.constraints and I want to validate input but allow it to be null, my POJO:

public class somePOJO{
    @NotNull
    @Size(min =2, max=50)
    @Pattern(regexp="^[A-Za-z \\s\\-]*$")
    private String country;

    @Size(min =2,max=50)
    @Pattern(regexp="^[A-Za-z \\s\\-]*$")
    private String state;
    //gettes, setters.....

}

I want to validate state for example with @Pattern and @size only if it not null.

Is there a way to do it with using custom annotations?

like image 503
Itsik Mauyhas Avatar asked Feb 03 '23 21:02

Itsik Mauyhas


1 Answers

This works out of the box as you would expect e.g. in Spring Boot, 2.1.0 (and also with Quarkus FWIW).

Here is the full version of the POJO (please notice, that I promote an immutable class):

package sk.ygor.stackoverflow.q53207105;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

public class SomePOJO {

    @NotNull
    @Size(min =2, max=50)
    @Pattern(regexp="^[A-Za-z \\s\\-]*$")
    private final String country;

    @Size(min =2,max=50)
    @Pattern(regexp="^[A-Za-z \\s\\-]*$")
    private final String state;

    public SomePOJO(String country, String state) {
        this.country = country;
        this.state = state;
    }

    public String getCountry() {
        return country;
    }

    public String getState() {
        return state;
    }

}

If you are concerned with empty strings you can accept them by adding a trailing pipe to the regular expression (which will mean "this expression OR empty string"), although this will break the Size() requirement:

@Pattern(regexp="^[A-Za-z \\s\\-]*$|")

Full version of the controller:

package sk.ygor.stackoverflow.q53207105;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

@RestController
public class ExampleController {

    @RequestMapping(path = "/q53207105", method = RequestMethod.POST)
    public void test(@Valid @RequestBody SomePOJO somePOJO) {
        System.out.println("somePOJO.getCountry() = " + somePOJO.getCountry());
        System.out.println("somePOJO.getState() = " + somePOJO.getState());
    }

}

Calling http://localhost:8080/q53207105 with:

{
    "country": "USA",
    "state": "California" 
}

Prints:

somePOJO.getCountry() = USA
somePOJO.getState() = California

Calling http://localhost:8080/q53207105 with:

{
    "country": "USA",
}

Prints:

somePOJO.getCountry() = USA
somePOJO.getState() = null

If you tell me your Spring boot version, I might help more.

like image 116
ygor Avatar answered Feb 06 '23 11:02

ygor