Supposons que j'ai un formulaire où je pourrais soumettre username(@NaturalId)
et password
pour un nouvel utilisateur.
Je voudrais ajouter l'utilisateur avec un username
unique. Comment utiliser les annotations @Valid
pour valider cette contrainte? Et si le nom d'utilisateur n'est pas unique, comment puis-je afficher cette information dans jsp via <form:error/>
?
Autant que je sache, il n'y a pas d'annotation pour le faire. Vous avez deux options
Premièrement, créez une annotation de validateur personnalisée. Ici est un très bon exemple. Appelez votre classe DAO et vérifiez la disponibilité dans l'implémentation du validateur
public boolean isValid(String object, ConstraintValidatorContext constraintContext) {
return userDAO.userNameAvailable(object); //some method to check username availability
}
OU
Définissez unique = true sur votre propriété dans votre classe d'entité.
@Column(unique = true)
private String userName;
Mais cela ne fonctionnera pas avec @valid, mais lève une exception sur la persistance. Vous devez utiliser une logique appropriée pour gérer cela.
La première solution n'est pas infaillible. Vérifiez ceci répondez à SO.
La seconde volonté n'échouera jamais.
UPDATE
Comme l'a commenté NimChimpsky, utiliser les deux ensemble constituera une solution concrète.
JSR-303 ne prend pas en charge ce que vous voulez (quelque chose comme une contrainte @Unique
). Vous devez écrire votre propre validateur. Comment cela peut être fait est expliqué ici: https://community.jboss.org/wiki/AccessingtheHibernateSessionwithinaConstraintValidator
Mais avant de faire cela, assurez-vous de lire cette réponse: https://stackoverflow.com/a/3499111/1981720
Et cette phrase de l'article précédent:
La raison pour laquelle @Unique ne fait pas partie des contraintes intégrées est le fait Qu'accéder à Session/EntityManager au cours d'une validation vous ouvre À des lectures fantômes potentielles.
Vous pouvez utiliser la classe de printemps préparée UserDetailsService, l'étendre et la personnaliser:
@Service
public class LoginDetailsServiceImpl implements UserDetailsService, Serializable {
@Autowired
LoginService loginService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (username == "" || username.isEmpty()) {
throw new UsernameNotFoundException(String.format("User %s is invalid!", username));
}
Login login = loginService.find(username);
if (login == null) {
throw new UsernameNotFoundException(String.format("User %s does not exist!", username));
}
if (!loginService.scheduleChecking(login.getScheduled())) {
throw new UsernameNotFoundException(String.format("User %s is not authorized this time!", username));
}
//....