2014-12-16 2 views
0

Я хотел бы иметь пользовательскую аннотацию, чтобы проверить, является ли электронное письмо в форме уникальным или нет. Aldready успешно создал аннотацию «ValidEmail».Пользовательская проверка

@Target({ ElementType.METHOD, ElementType.FIELD }) 
@Retention(RetentionPolicy.RUNTIME) 
@Constraint(validatedBy = EmailValidatorImpl.class) 
public @interface ValidEmail { 
    String message() default "{error.validEmail}"; 
    String[] groups() default {}; 
} 

класс реализации:

public class EmailValidatorImpl implements ConstraintValidator<ValidEmail, String> { 

private static String EMAIL_PATTERN = "^[\\w\\.-][email protected]([\\w\\-]+\\.)+[A-Z]{2,4}$"; 
private Pattern pattern; 
private Matcher matcher; 

@Override 
public void initialize(ValidEmail annotation) { 
    pattern = Pattern.compile(EMAIL_PATTERN, Pattern.CASE_INSENSITIVE); 
} 

@Override 
public boolean isValid(String email, ConstraintValidatorContext context) { 
    return isValidEmail(email); 

} 

private boolean isValidEmail(String email) { 
    CharSequence emailstr = email; 
    matcher = pattern.matcher(emailstr); 
    return matcher.matches(); 
} 

}

Я хотел бы теперь, чтобы построить "uniqueEmail" аннотацию.

public class UniqueEmailValidatorImpl implements ConstraintValidator<UniqueEmail, String> { 

private UserServices userServices; 

@Override 
public void initialize(UniqueEmail annotation) { 
    this.userServices = annotation.getUserServices(); 
} 

@Override 
public boolean isValid(String email, ConstraintValidatorContext context) { 
    return isUniqueEmail(email); 

} 

private boolean isUniqueEmail(String email) { 
    try { 
     userServices.findByEmail(email); 
    } catch (UserDoesNotExistException e) { 
     return true; 
    } 
    return false; 

} 

}

Поскольку я следую IoC (с весны), я действительно не люблю создания экземпляра слоя обслуживания пользователя непосредственно в методе инициализации. Как бы вы предложили решить эту проблему? Может ли аннотация ссылаться на экземпляр?

@Override 
public void initialize(UniqueEmail annotation) { 
    this.userServices = annotation.getUserServices(); 
} 

Любые предложения будут оценены. Спасибо!

+0

Хм, есть уже неплохой API для проверки электронной почты (javamail), почему бы вам не использовать его? – fge

+0

Вы правы, но мне нужно проверить мою базу данных, если письмо существует. «ValidEmail» должен был только попробовать это. – Apokai

ответ

1

Как правило, я бы не рекомендовал использовать ваши Услуги в ваших валидаторах (относительно MVC и быть свободным от побочных эффектов). Как вы используете Spring, почему не вводите свою услугу?

@Autowired 
public void setUserService(final UserServices userServices) { 
    this.userServices = userServices 
} 
+0

Hi, первый thk для ответа. Если вы не порекомендуете, каким будет ваш подход к этому? – Apokai

+0

Валидатор должен, по-моему, быть как можно меньшим, чтобы его можно было повторно использовать. Я лично брошу исключение в свой бизнес-логический уровень (например, уровень обслуживания) и обработаю его соответствующим образом. Я уверен, что есть много людей, которые не согласятся. Тем не менее @Autowired решит вашу проблему, если вам нужен/нужен доступ к вашей БД из ваших валидаторов. – wgitscht

1

Вы должны просто ввести свою зависимость от userServices. В зависимости от того, как вы структурировали свой проект, это либо автоматически, либо инсертируется конструктором, либо вводится с помощью setter.

Это далеко более ограничительными, чтобы сделать это в другом порядке, как и аннотации требуют, чтобы все установить внутри них быть константой во время компиляции, так что вы можете только действительно String и Class объекты там так или иначе, и вы 'd должны идти, чтобы создать объект, о котором вы заботитесь, через отражение. Имеет смысл использовать Spring для этого.

Кроме того, ваш фактический подход к проверке является подозрительным. Я ожидаю, что findByEmail должен вернуть, существует ли по электронной почте пользователь по электронной почте в базе данных; то есть boolean. Использование try...catch таким образом кажется неуместным и очень неэффективно, так как ваш валидатор, скорее всего, будет называться очень часто.

1

Почему бы вам просто не ввести UserServices?

@Autowired 
private UserServices userServices; 
Смежные вопросы