访问ConstraintValidator中的ServletContext

时间:2017-02-04 15:56:26

标签: servlets java-ee bean-validation

我希望使用约束验证器验证输入。我的问题是我需要ServletContext中包含的一些信息,例如属性文件的路径,来验证请求bean。我发现使用Spring我可以使用@Autowired注释,但不幸的是我不能使用这个框架。

约束:

@Constraint(validateBy = MyValidationClass.class)
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface  MyValidation {
    ...
}

我希望在约束验证器中做的事情是这样的:

@Override
public boolean isValid(RequestBean value, ConstraintValidatorContext context) {
    Properties props = servletContext.getAttribute("ws.props")
    // my validation
}

我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:0)

这可能不是最佳解决方案。 (编辑:你最终可以在我的编辑中找到更好的解决方案)

但我想你可以创建一个ServletContainerInitializer来将ServletContext存储在一个静态变量中,然后在初始化程序中访问它。

我在这里发现的不是很好,因为你对静态方法有很深的依赖性。但是否则你可能会找到一种方法来挂钩实例化ConstraintValidator的进程。

编辑:我刚刚查看了Hibernator Validator文档。如果您使用的是Hibernator Validator实现,我想这一章对您来说很有意思:https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#__code_constraintvalidatorfactory_code

根据这一点,我会创建一个自己的ConstraintValidatorFactory和一个新的界面ServletContextAware,其中包含一个setter setServletContext(ServletContext)。 然后验证器工厂可以检查应该实例化的类是否实现此接口并设置ServletContext。 新ConstraintValidatorFactory可用于创建将用于创建所需验证程序的新ValidatorFactory

只是一些未经检查的代码示例:

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();