Question

Cet exemple est un peu controuvé; Je l'ai simplifié pour éliminer les détails superflus et de se concentrer sur le problème que j'ai. J'ai un validateur qui ressemble à ceci:

@Component
public class UniqueUsernameValidator implements ConstraintValidator<UniqueUsername, String> {

    @Autowired
    UsernameService usernameService;

    @Override
    public void initialize(UniqueUsername uniqueUsername) {
    }

    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        return !usernameService.exists(s);
    }   
}

J'appelle le validateur de mon contrôleur comme ceci:

@RequestMapping
public void checkUsername(Model model, User user) {
    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    Validator validator = factory.getValidator();

    Set<ConstraintViolation<User>> constraintViolations = validator.validateProperty(user, "username");
    model.addAttribute("error", constraintViolations.size() > 0);
}

Cependant, je continue à obtenir une exception NullPointerException. J'ai ajouté un point d'arrêt dans mon validateur et a vu que usernameService était null. Pourquoi est-ce pas s'autowired? Au début, je pensais que c'était parce que je ne l'avais pas annoté le validateur avec @Component, mais je dois toujours le même problème, même après l'annotant. La classe UsernameService a déjà été annoté avec @Service et je peux vérifier que son constructeur est appelé se.

Je suis nouveau au printemps, donc je ne suis même pas sûr si elle est bien câbler un service dans un validateur. Qu'est-ce que je fais mal?

Était-ce utile?

La solution

Au printemps, vous devez obtenir ValidatorFactory (ou Validator lui-même) par l'intermédiaire LocalValidatorFactoryBean au lieu de Validation.buildDefaultValidatorFactory(), comme décrit dans le de référence.

@Autowired
Validator validator;

@RequestMapping 
public void checkUsername(Model model, User user) { 
    Set<ConstraintViolation<User>> constraintViolations = validator.validateProperty(user, "username"); 
    model.addAttribute("error", constraintViolations.size() > 0); 
} 

-

<bean id="validator"
    class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

EDIT: Mais peut-être la meilleure façon de le faire est d'utiliser la validation automatique de Spring MVC avec annotation @Valid:

@RequestMapping  
public void checkUsername(Model model, @Valid User user, BindingResult result) {  
    if (result.hasErrors()) {   
        ...
    }
}

Cela nécessite également <mvc:annotation-driven/> dans la configuration.

Autres conseils

Au lieu de créer un nouveau validateur, vous devez lier automatiquement ou injecter au contrôleur. Le NPE du service ne sont pas injectés en tant que votre validateur n'est pas créé / géré par ressort.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top