Home > database >  ConstraintValidator on Rest layer not working
ConstraintValidator on Rest layer not working

Time:03-12

I'm working on a base repo in which I want to add a custom validation example in the rest layer, but it is not working, is not printing the flags at the moment of the validation, it just go right through the controller layer instead of the validator class. What am I missing?

This is the rest layer:

@RequestMapping("equipment/")
public interface DeviceREST extends RestConstants {

    @GetMapping("test")
    @Produces(MediaType.APPLICATION_JSON)
    BaseResult<UserDTO> test(
            /* Example of a validation layer before moving forward device impl */
            @QueryParam("genre") @Valid @AllowedGenderExampleValidations final String genre
    ) throws Exception;
}

AllowedGenderExampleValidations class

@Documented
@Retention(RUNTIME)
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Constraint(validatedBy = ExampleValidationsValidator.class)
public @interface AllowedGenderExampleValidations {
    String message() default "Invalid value for genre query param";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

class ExampleValidationsValidator implements ConstraintValidator<AllowedGenderExampleValidations, String> {
    private List<String> allowedGenres = new ArrayList<>();

    @Override
    public void initialize(AllowedGenderExampleValidations constraint) {
        System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
        List<GenderExampleEnum> allowedValues = new ArrayList<>(EnumSet.allOf(GenderExampleEnum.class));
        for(GenderExampleEnum g : allowedValues) {
            this.allowedGenres.add(g.name().toLowerCase());
        }
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
return value != null && this.allowedGenres.contains(value) && this.allowedGenres.contains(value.toLowerCase());
    }
}

GenderExampleEnum class

public enum GenderExampleEnum {
    M("Man"),
    W("Woman"),
    O("Other");

    private final String genre;

    public String getGenre() { return genre; };

    GenderExampleEnum(String genre) { this.genre = genre; }

    public static GenderExampleEnum fromValue(String code) throws IllegalArgumentException {
        for(var g : GenderExampleEnum.values()) {
            if(code.toLowerCase().equalsIgnoreCase(g.name())) {
                return g;
            }
        }
        return GenderExampleEnum.O;
    }
}

Controller class

@Controller
public class DeviceImpl implements  DeviceREST {

    private static final Logger logger = LoggerFactory.getLogger(DeviceImpl.class);

    @Autowired private DeviceService deviceService;
    @Autowired private DataTransferUtil dataTransferUtil;

    @Override
    public BaseResult<UserDTO> test(String genre) throws Exception {
        var serviceResponse = deviceService.testFirstMethod();
        var mappingResponse = dataTransferUtil.mapFirstTestMethod(serviceResponse);
        return new BaseResult<UserDTO>(mappingResponse);
    }
}

Test response, missing validations for query param

URL: localhost:8080/equipment/test?genre=o

enter image description here

CodePudding user response:

I can't derive for sure from the context which Spring Boot version you are using, but for Spring boot 2.3.0 or later, a common mistake is relying on the spring-boot-starter-validation that is not included by default anymore.

You should make sure to add the following dependency if you want to use validation in a Spring Boot 2.3.0 or up project:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

See spring docs here.

Could you please let me know if this solved your issue by replying or accepting this answer?

CodePudding user response:

I should have added this annotation in the Rest Layer -> "@Validated" to make it work, without that dependency, validators won't be triggered

  • Related