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
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