繁体   English   中英

如何在ConstraintValidator中自动装配服务

[英]How to autowire service in ConstraintValidator

我正在使用Spring MVC编写我的应用程序。 我想验证用户注册时数据库中是否存在电子邮件。 我编写了自己的注释约束,名为UniqueEmail

我的用户实体User.java

@Entity
@Table(name="users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column(name = "email", length = 100, nullable = false, unique = true)
    @NotEmpty
    @Email
    @UniqueEmail(message = "E-mail is not unique")
    private String email;

    @Column(name = "password", nullable = false)
    @NotEmpty
    @Size(min = 5, message = "size must be more 5")
    private String password;
}

我的注释约束UniqueEmail.java

@Target({FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = UniqueEmailValidator.class)
@Documented
public @interface UniqueEmail {
    String message() default "Email is exist";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

我的验证器UniqueEmailValidator.java

@Component
public class UniqueEmailValidator implements ConstraintValidator<UniqueEmail, String> {

    @Autowired
    private UserService userService;

    @Override
    public void initialize(UniqueEmail uniqueEmail) {
    }

    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        try {
            return userService.isExistEmail(s);
        } catch (Exception e) {
            System.out.println(e);
            return false;
        }
    }
}

此代码适用于应用程序。

当我运行我的测试代码时,它返回NullPointerException。 在我的验证类中, userService为null。

我已阅读http://docs.spring.io/spring/docs/3.0.0.RC3/reference/html/ch05s07.html无法解决任何问题。

任何的想法?

更新

我使用JUnit。 UserClassTest.java

@ContextConfiguration("file:src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml")
public class UserClass {

    private static Validator validator;

    @BeforeClass
    public static void setup() {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        validator = factory.getValidator();
    }

    @Test
    public void emailIsUnique() {

        User user = new User();
        user.setEmail("mail@example.com"); // I've written exist email in DB.

        Set<ConstraintViolation<User>> constraintViolations = validator.validateProperty(user, "email");

        assertEquals(1, constraintViolations.size());
        assertEquals("E-mail is not unique", constraintViolations.iterator().next().getMessage());
    }
}

更新

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:mvc="http://www.springframework.org/schema/mvc"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

<context:component-scan base-package="ru.yadoka"/>

<import resource="db/db-config.xml"/>

<!-- Apache tiles -->
<bean id="tilesConfigurer"
      class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
    <property name="definitions">
        <list>
            <value>/WEB-INF/tiles.xml</value>
        </list>
    </property>
</bean>

<bean id="viewResolver"
      class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView"/>
</bean>

<!-- Mapping resources from theme -->
<mvc:resources mapping="/css/**" location="/resources/css/"/>
<mvc:resources mapping="/js/**" location="/resources/js/"/>
<mvc:resources mapping="/fonts/**" location="/resources/
<mvc:annotation-driven/>

您是否在bean上下文中配置了Validator。 如果您通过Validation.buildDefaultValidatorFactory()引导Validator ; 你绕过Spring机制,你得到一个不知道Spring bean和组件的Validator。 因此注射不起作用。 在您的测试中,您希望获得Spring提供的Validator。

如果您的主要代码正常工作,那么应该直接进行测试。 您需要在测试类上使用@ContextConfiguration,有关详细信息,请参阅此内容: http ://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/testing.html

一般来说,有两种方法可以测试:

  • 单元测试
  • 整合测试

对于单元测试,您需要创建UniqueEmailValidator的实例并在该实例上设置UserService(通常是模拟UserServer)。

对于集成测试,您需要如上所述初始化spring上下文。

您可以调用注射所有@Autowired服务:

@Override
public void initialize(UniqueEmail uniqueEmail) {
   org.springframework.web.context.support.SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM