【问题标题】:Using @Autowired component in custom JSR-303 validator在自定义 JSR-303 验证器中使用 @Autowired 组件
【发布时间】:2013-10-25 14:37:30
【问题描述】:

我正在尝试为我的模型类实现一个自定义验证器,它可以自动装配我的自定义 bean(通过 @Component 声明)。 在此,我关注了Spring documentation on that topic。我的AuthenticationFacade对象是按照this tutorial实现的。

但是,在运行我的测试时,Validator 对象中的 autowired 属性始终是 null。这是为什么呢?

以下是我的代码的相关部分:

我的自定义 beanAuthenticationFacadeImpl.java

@Component
public class AuthenticationFacadeImpl implements AuthenticationFacade {
    boolean hasAnyRole(Collection<String> roles) {
        // checks currently logged in user roles
    }
}

我的自定义约束HasAnyRoleConstraint.java

@Constraint(validatedBy = HasAnyRoleConstraintValidator.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface HasAnyRole {
    String[] value();
    String message() default "{HasAnyRole}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

我的自定义验证器HasAnyRoleConstraintValidator.java

@Component
public class HasAnyRoleConstraintValidator implements ConstraintValidator<HasAnyRole, Object> {
    @Autowired
    AuthenticationFacade authenticationFacade;

    private String[] roles;

    @Override
    public void initialize(HasAnyRole hasAnyRole) {
        this.roles = hasAnyRole.value();
    }

    @Override
    public boolean isValid(Object target, ConstraintValidatorContext constraintValidatorContext) {
        return target == null || authenticationFacade.hasAnyRole(Arrays.asList(this.roles));
    }
}

模型类Article.java

@Entity
public class Article {
    // ...
    @HasAnyRole({"EDITOR", "ADMIN"})
    private String title;
    // ...
}

服务对象ArticleServiceImpl.java

@Service
public class ArticleServiceImpl implements ArticleService {
    @Autowired
    private ArticleRepository articleRepository;

    @Autowired
    private AuthenticationFacade authenticationFacade;

    @Autowired
    private Validator validator;

    @Override
    @PreAuthorize("hasAnyRole('ADMIN', 'EDITOR')")
    public boolean createArticle(Article article, Errors errors) {
        articleRepository.save(article);
        return true;
    }

输入createArticle 方法的Errors 对象旨在来自Spring 控制器,该控制器获得一个带有@Valid 注释的模型对象。

存储库ArticleRepository.java,使用 Spring Data JPA 的 JpaRepository

public interface ArticleRepository extends JpaRepository<Article, Long> {
}

【问题讨论】:

    标签: java spring dependency-injection spring-security bean-validation


    【解决方案1】:

    我现在通过放弃 Validator 类的依赖注入解决了这个问题,而是在构造函数中实例化 AuthenticationFacadeImpl 的实例。 仍然很有趣,尽管如何将控制器中 @Valid 的使用与自定义验证器 + 模型中的 @Autowired 属性结合起来,而无需在代码中显式调用验证器...

    【讨论】:

      【解决方案2】:

      如果您的验证器是在 Spring 上下文之外实例化的,那么您可以使用 Spring 的 AOP @Configurable 魔法在上下文中注册它并进行自动装配工作。您所要做的就是用@Configurable 注释HasAnyRoleConstraintValidator 并启用编译时间或加载时间方面的编织。

      【讨论】:

        猜你喜欢
        • 2015-07-31
        • 2015-03-28
        • 2011-08-09
        • 1970-01-01
        • 2023-03-29
        • 2018-10-02
        • 2011-09-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多