2014-01-24 53 views
1

我正在使用Spring MVC寫我的應用程序。 我想驗證用戶註冊時數據庫中是否存在電子郵件。我寫了自己的註釋約束,名爲UniqueEmail如何在ConstraintValidator自動裝配服務

我的用戶實體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爲空。

我讀過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("[email protected]"); // 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/> 

+0

如果userService爲空,這意味着你沒有它正確自動裝配。 – Eugene

+0

您是否在applicationcontext中使用? – Koitoer

+0

Kiotoer - yes''。在我的控制器中,userService自動裝配正確。 – Mufanu

回答

0

如果你的主代碼工作,那麼它應該是直截了當地讓您的測試工作。 您需要使用@ContextConfiguration在您的測試類,看到更多細節: http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/testing.html

一般情況下,有2種方式來測試這一點:

  • 單元測試
  • 集成測試

對於單元測試,您需要創建一個UniqueEmailValidator實例並在該實例上設置一個UserService(通常是一個模擬UserServer)。

對於集成測試,您需要像上面提到的那樣初始化spring上下文。

+0

我已更新我的帖子。如何創建UniqueEmailValidotor的實例並設置UserService? – Mufanu

+0

你可以發佈mvc-dispatcher-servlet.xml – Solubris

+0

我已經添加了配置發佈。 – Mufanu

1

你沒有在bean上下文中配置Validator嗎?如果您正在引導Validator via Validation.buildDefaultValidatorFactory();你正在繞過Spring機制,你會得到一個不知道Spring bean和組件的Validator。因此注射不起作用。在你的測試中,你想獲得Spring提供的驗證器。

0

您可以撥打注入所有@Autowired服務:

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