I hope someone would have some ideas, because I’m stuck at this for 2 days now… I have a restAPI (not my project, I’m unable to modify it) that was recently updated by the owning team. Let’s say I have the following:
@PostMapping("/api/post")
ResponseEntity<?> post(HttpServletRequest httpServletRequest, @Valid PostParameter postParameter) {
...
}
Where PostParameter is a base class, which I’m extending. Here comes the problem. Certain fields of this class needs to be validated based on properties that the application was started with. For simplicity’s sake let’s say I have this:
public final class ResourceCreateParameter extends PostParameter {
@CustomMessageConstraint
private final String message;
// omitted
}
where I naively implemented my constraint as:
@Target({ElementType.FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = CustomMessageValidator.class)
public @interface CustomMessageConstraint {
String message() default "Message is not allowed"
Class<?>[] group() default {};
Class<? extends Payload>[] payload() default {};
}
and my validator is again fairly simple:
@Component
public class CustomMessageValidator
implements ConstraintValidator<CustomMessageConstraint, String> {
private final String[] allowedValues;
public CustomMessageValidator(ValidatorProperties validatorProperties) {
this.allowedValues = validatorProperties.allowedValues();
}
@Override
public boolean isValid(String s, ConstraintValidatorContext context) {
return Arrays.stream(allowedValues).anyMatch(v -> v.equalsIgnoreCase(s));
}
}
Upon trying it out however, allowedValues is null as DI is not taking effect. I’ve also tried defining LocalValidatorFactory bean, but @Valid still refuses to do the validation. The only way I could validate is by modifying the (in my case unmodifyable piece of code) aka the controller. There, I can inject an instance of CustomMessageValidator (even without LocalValidatorFactory bean present) and I can manually trigger .validate method.
Is there a way, around it? I need to use the ConfigurationProperties to read the value that is allowed, and the validation is handled via @Valid.