'How to pass information from ConstraintValidator to Controller?
I have a custom ConstraintValidator.
public class UrlValidator implements ConstraintValidator<ValidUrl, RemoteFile> {
@Override
public boolean isValid(RemoteFile value, ConstraintValidatorContext context) {
return true;
}
}
The RemoteFile is a very simple DTO.
public record RemoteFile(String url) {}
I'm using UrlValidator with my custom annotation.
@Documented
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UrlValidator.class)
public @interface ValidUrl {
String message() default "invalid file";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Finally I'm using the annotation inside my controller.
@PostMapping("/hello")
public String remote(@ValidUrl @RequestBody RemoteFile body) {
// do stuff inside the controller
}
I'd like to pass some information from my validator to my controller. I found a way to do this but I was wondering why the other way does not work.
Here is what works.
@Override
public boolean isValid(RemoteFile value, ConstraintValidatorContext context) {
RequestContextHolder.getRequestAttributes()
.setAttribute("key", "value", RequestAttributes.SCOPE_REQUEST);
return true;
}
I can afterwards access the information in my controller.
@PostMapping("/hello")
public String remote(@ValidUrl @RequestBody RemoteFile body) {
var value =
(String)
RequestContextHolder.getRequestAttributes()
.getAttribute("key", RequestAttributes.SCOPE_REQUEST);
// do stuff inside the controller
}
Then I tried something different because I thought there is a simpler way. However this DOES not work and I do not understand why. Use the HttpServletRequest and set an attribute.
@Autowired HttpServletRequest request;
@Override
public boolean isValid(RemoteFile value, ConstraintValidatorContext context) {
request.setAttribute("key", "value");
return true;
}
Use the attribute directly in the controller method.
@PostMapping("/remote")
public String remote(
@ValidUrl @RequestBody RemoteFile body,
@RequestAttribute String key
) {
// do stuff in the controller
}
However I'm always getting the error message
Resolved [org.springframework.web.bind.ServletRequestBindingException: Missing request attribute 'key' of type String]
I do not understand the error message. The attribute should be there because the validator should have set it. Any ideas? I'm lost!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
