【问题标题】:Get HttpServletRequest in JSR-303 Bean Validation在 JSR-303 Bean Validation 中获取 HttpServletRequest
【发布时间】:2015-03-09 19:22:35
【问题描述】:

我的应用程序中有一个使用 cookie (request.getCookies) 来验证验证码的验证。

我想为此验证码验证创建一个 ConstraintValidator,因此它与其他 bean 的属性一起被验证 - 正如 JSR-303 Bean Validation 所指定的那样。

有没有办法在 ConstraintValidator 中检索 HttpServletRequest?

【问题讨论】:

    标签: java spring validation


    【解决方案1】:

    假设(由于存在标签)您使用的是 Spring,最新版本是一个 (>=2.5.1),这应该很简单

    package org.yourapp.controller.validation;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.context.support.SpringBeanAutowiringSupport;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.validation.ConstraintValidator;
    import javax.validation.ConstraintValidatorContext;
    
    public class YourValidator implements ConstraintValidator<YourValidatorAnnotaion, String> {
        // here should be autowired a proxy to currently undergoing request
        @Autowired
        private HttpServletRequest request;
    
        @Override
        public void initialize(YourValidatorAnnotaion constraintAnnotation) {
            // this should autowire all dependencies of this class using
            // current application context
            SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
        }
    
        @Override
        public boolean isValid(String value, ConstraintValidatorContext context) {
            // here goes your custom logic for validation, like matching
            // captcha challenge to captcha response, but i am not doing
            // this for you, as i don't know what it supposed to be, so
            // i simply test presence of cookies.
            return request.getCookies().length > 0;
        }
    }
    

    为了完整起见,这里是一个示例@YourValidatorAnnotaion 实现:

    package org.yourapp.controller.validation;
    
    import javax.validation.Constraint;
    import javax.validation.Payload;
    import java.lang.annotation.Retention;
    import java.lang.annotation.Target;
    
    import static java.lang.annotation.ElementType.*;
    import static java.lang.annotation.RetentionPolicy.RUNTIME;
    
    @Constraint(validatedBy = YourValidator.class)
    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
    @Retention(RUNTIME)
    public @interface YourValidatorAnnotaion {
        String message() default "No cookies - no validation";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
    }
    

    就是这样。现在,如果您使用 @YourValidatorAnnotaion 注释您的 DTO 字段,那么只要在请求标头中没有 cookie 的情况下调用具有此类 @Valid @RequestBody 参数的控制器时,您就会收到错误消息。

    【讨论】:

    • 您有机会为此提供参考吗?我对其进行了测试,它似乎可以工作,但是ConstraintValidator 的实现必须是线程安全的,因为它们可以重复使用。这似乎不可能是线程安全的。谢谢。
    • 但它是线程安全的。被注入的 HttpServletRequest 只是一个代理,它对应于当前的实际请求,并且 J2EE/Spring 中的所有请求处理(包括验证)都是在线程本地完成的,这意味着每个线程对整个处理都有不同的请求。
    • IntelliJ 向我显示此错误:Could not autowire. No beans of 'HttpServletRequest' type found. 但代码以某种方式工作。我在调试模式下检查。这是为什么呢?
    • @mantri IntelliJ 显然没有索引注册该 bean 的 spring 上下文。除非仔细配置,否则 IntelliJ 对 spring 上下文的检查并不是特别可靠,尤其是 spring-boot 和其他运行时 bean 发现机制的情况。
    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 2012-03-30
    • 2012-04-05
    • 1970-01-01
    • 2011-12-28
    • 2016-06-19
    • 1970-01-01
    • 2015-01-10
    相关资源
    最近更新 更多