Issue
I wish to validate the input using a constraint validator. My problem is that I need some information contained in ServletContext
, for example the path of properties file, to validate the request bean. I find that with Spring I can use @Autowired
annotation, but unfortunately I can't use this framework.
The constraint:
@Constraint(validateBy = MyValidationClass.class)
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface MyValidation {
...
}
And what I wish do in constraint validator is something like this:
@Override
public boolean isValid(RequestBean value, ConstraintValidatorContext context) {
Properties props = servletContext.getAttribute("ws.props")
// my validation
}
How can I achieve this?
Solution
This might not be the best solution. (EDIT: You could find a better solution in my EDIT at the end)
But I guess you could just create a ServletContainerInitializer
that stores the ServletContext
in a statical variable and access this inside the initializer.
What I don't find very nice here is that you than have a deep dependency to a static method. But otherwise you might find a way to hook into the process that instantiates the ConstraintValidator
.
EDIT: I just looked up the Hibernator Validator documentation. And I guess this chapter here would be interesting for you, if you are using the Hibernator Validator implementation: https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#__code_constraintvalidatorfactory_code
According to this I would create an own ConstraintValidatorFactory
and a new interface ServletContextAware
with one setter setServletContext(ServletContext)
.
Then the validator factory can check if the class that should be instantiated implements this interface and set the ServletContext
.
The new ConstraintValidatorFactory
could be used to create a new ValidatorFactory
that will be used to create the required validators.
Just some not-checked code examples:
interface ServletContextArea {
public void setServletContext(ServletContext context);
}
public class ServletContextConstraintValidatorFactory implements ConstraintValidatorFactory {
private ServletContext servletContext;
public ServletContextConstraintValidatorFactory(ServletContext servletContext) {
this.servletContext = servletContext;
}
@Override
public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
// create instance from key as validator
if(validator instanceof ServletContextAware) {
((ServletContextAware) validator).setServletContext(this.servletContext);
}
//...
return validator;
}
@Override
public void releaseInstance(ConstraintValidator<?, ?> instance) {
//...
}
}
// somewhere in the code where you have the servletContext available
ValidatorFactory validatorFactory = Validation.byDefaultProvider()
.configure()
.constraintValidatorFactory( new ServletContextConstraintValidatorFactory(servletContext) )
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
Answered By - chris922
Answer Checked By - Candace Johnson (JavaFixing Volunteer)