2017-06-14 42 views
3

我使用Spring 4和休眠5是否有可能讓我的自定義驗證註釋在持續時被忽略?

我有用戶類與密碼字段與自定義驗證。

我需要驗證它,而表單綁定爲8個字符長,包括小寫字母,大寫字母和數字。

當用戶輸入密碼時它是有效的,但是當我編碼時它是無效的。

那麼有沒有辦法讓我的自定義驗證註釋被忽略持續?

我知道我可以爲未加密的密碼創建不同的字段,或者使數據傳輸對象驗證它,然後將其數據分發給用戶。 但我對註釋參數化的可能性感興趣。

@Entity 
@Table(name = "user") 
public class User { 
//other fields 

@NotNull 
@NotEmpty 
@ValidPassword 
@Column(name = "password", nullable = false, length = 60) 
private String password; 
//getters and setters 
} 

我的驗證

@Target({ TYPE, FIELD, ANNOTATION_TYPE }) 
@Retention(RUNTIME) 
@Constraint(validatedBy = PasswordValidator.class) 
@Documented 
public @interface ValidPassword { 
String message() default "Password is too short! Must be 8 digits and include lowercase, uppercase letters and numbers."; 

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

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

public class PasswordValidator implements ConstraintValidator<ValidPassword, String> { 

private Pattern pattern; 
private Matcher matcher; 
private static final String PATTERN = "((?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,})"; 

@Override 
public void initialize(ValidPassword constraintAnnotation) { 
} 

@Override 
public boolean isValid(String password, ConstraintValidatorContext context) { 
    return (validate(password)); 
} 

private boolean validate(String password) { 
    pattern = Pattern.compile(PATTERN); 
    matcher = pattern.matcher(password); 
    return matcher.matches(); 
} 
} 

控制方法

@RequestMapping(value = "/registeruser", method = RequestMethod.POST) 
public String registerUser(@ModelAttribute("user") @Valid User user, BindingResult result, Model model) { 
    if (result.hasErrors()) { 
     model.addAttribute("errorSummary", result.getFieldErrors().stream() 
       .map(e -> e.getField() + " error - " + e.getDefaultMessage() + " ").collect(Collectors.toList())); 
     model.addAttribute("user", user); 

    } else { 
     User registered = null; 
     registered = createUserAccount(user, result); 

     if (registered == null) { 
      model.addAttribute("errorSummary", "User with this email already registered!"); 
      model.addAttribute("user", user); 
      return "registration"; 
     } 
     model.addAttribute("flashMessage", "User registered successfully!"); 
    } 

    return "registration"; 
} 

UserService實現方法(在這裏我編碼我的密碼)

@Transactional 
@Override 
public User registerNewUserAccount(User user) throws EmailExistsException { 

    if (emailExist(user.getEmail())) { 
     throw new EmailExistsException("There is an account with that email address:" + user.getEmail()); 
    } 

    if (user.getPassword() == null) { 
     user.setPassword(new BigInteger(130, new SecureRandom()).toString(32)); 
     System.out.println("+++++++++++++++" + user.getPassword()); 
    } 
    user.setPassword(passwordEncoder.encode(user.getPassword())); 
    user.setUserRole(new HashSet<UserRole>(1)); 
    user.getUserRole().add(new UserRole(user, Constants.RoleType.USER.name())); 
    save(user); 
    return user; 
} 
+0

Waht確實「無效,當我編碼」,確切地說,在代碼中的哪個位置得到該錯誤? – zaph

+0

我在一個月前遇到過這樣的情況,當時我只想在持久化上運行驗證。請參閱:https://stackoverflow.com/questions/43964065/hibernate-validations-on-save-insert-only/43984952#43984952。您必須將驗證設置爲在「javax.persistence.validation.group.pre-update」(可能是「javax.persistence.validation.group.pre-remove」)期間執行。看到完整的文檔在這裏:https://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/additionalmodules.html –

+0

@ zaph當用戶輸入正確的密碼是有8位數等等,當我使用'passwordEncoder.encode(user。getPassword())'它現在變得更長了(例如:$ 2a $ 10 $ 3/ufbdU3qMnn7e3IQ7hkjubrdRJrD7kKieAqflKEDvZ8b7DY8eUcu),所以驗證失敗 –

回答

1

默認情況下,所有約束都會進行驗證。或者你也可以指定Grouping Constraints

您可以通過創建一個接口創建組:

interface FormValidationGroup{} 

和註釋password場這樣的:

@ValidPassword(groups = FormValidationGroup.class) 
private String password; 

文檔爲Custom Constraints annotations,其中groups參數被提及。

除非您指定驗證組,否則Hibernate驗證程序現在應忽略password字段。爲了指定一個用於驗證Spring MVC處理程序方法參數的組,請使用Validated註釋而不是Valid。例如:

String registerUser(@ModelAttribute @Validated(FormValidationGroup.class) User user, 
     BindingResult result, Model model) { 
    if (result.hasErrors()) { 
+0

這很有用。但是,如何讓我的自定義組在form綁定上得到驗證,所以我可以使用BindingResult'hasErrors()'方法? –

+1

我更新了我的答案,以展示如何使用Spring MVC和'BindingResult'的自定義組 –

相關問題