4

I have a controller method like listed below whose argument is annotated with @Valid to validate PasswordChange object using a Hibernate validator @Constraint. Both PasswordChange and a sample constraint are listed below. As you can see, I am injecting up loginDao inside the constraint. Is this an anti-pattern ?

The other alternative I can think of is injecting the daos into the PasswordChange object so that the loginDao's are available inside the implementations of ConstraintValidator<A, V>. Somebody said that mixing data with business logic is an anti-pattern in spring.

Any suggestions are welcome.

Controller Method


@RequestMapping(value = "/passwordChange", method = RequestMethod.POST)
public @ResponseBody PasswordInfo passwordInfo(@RequestBody @Valid PasswordChange passwordChange)
 throws PasswordChangeException {
 return passwordService.changePassword(passwordChange.getLoginKey(), passwordChange.getOldPassword(), passwordChange.getNewPassword());
}

PasswordChange Bean


public class PasswordChange {
 @LoginAttemptsExceeded
 private String loginKey;
 private String oldPassword;
 private String newPassword;
 @Autowired
 private LoginDao loginDao;
 private LoginEntity login;
 private Person person;
 public PasswordChange() { 
 }
 public PasswordChange(String loginKey, String oldPassword, String newPassword) {
 this.loginKey = loginKey;
 this.oldPassword = oldPassword;
 this.newPassword = newPassword; 
 }
 @PostConstruct
 public void postInit() {
 login = loginDao.findByLogin(loginKey);
 person = login.getCorePerson();
 }
}

Sample Constraint


@Target({ FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = LoginAttemptsExceededValidatorLoginId.class)
@Documented
public @interface LoginAttemptsExceeded {
 String message() default "{com.mrll.global.core.constraint.loginAttemptsExceeded}";
 Class<?>[] groups() default {};
 Class<? extends Payload>[] payload() default {};
}

Sample Constraint Validator


public final class LoginAttemptsExceededValidatorLoginId implements ConstraintValidator<LoginAttemptsExceeded, String> {
 @Resource
 private LoginDao loginDao;
 private LoginAttemptsExceeded loginAttemptsExceeded;
 @Override
 public void initialize(final LoginAttemptsExceeded loginAttemptsExceeded) {
 this.loginAttemptsExceeded = loginAttemptsExceeded;
 }
 /**
 * Validation fails if the login attempts have exceeded the preset number.
 * @param loginId
 * @param constraintValidatorContext
 * @return
 */
 @Override
 public boolean isValid(final String loginId, final ConstraintValidatorContext constraintValidatorContext) {
 if(StringUtility.IsEmpty(loginId)) return false;
 return !loginDao.findByLogin(loginId).isLoginAttemptsExceeded();
 }
}
asked Apr 20, 2014 at 18:17

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.