web-dev-qa-db-fra.com

Comment @Valider un nom d'utilisateur unique au printemps?

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/>?

14
user902691

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.

19
shazinltc

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.

2
lunr

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));
        }
      //....
0
Pasha Gharibi