Pregunta

Este ejemplo es un poco artificial; He simplificado para eliminar detalles superfluos y centrarse en el problema que estoy teniendo. Tengo un validador que tiene este aspecto:

@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);
    }   
}

Me llaman el validador de mi controlador de la siguiente manera:

@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);
}

Sin embargo, me siguen dando una excepción NullPointerException. He añadido un punto de interrupción en mi validador y vio que era usernameService null. Por qué no está consiguiendo autowired? Al principio pensé que era porque no había anotado el validador con @Component, pero todavía tengo el mismo problema, incluso después de la anotación de la misma. La clase UsernameService ya se ha anotado con @Service y puedo comprobar que su constructor está recibiendo llamadas.

Soy nuevo en primavera, así que no estoy seguro si está bien para conectar un servicio en un validador. ¿Qué estoy haciendo mal?

¿Fue útil?

Solución

En la primavera, lo que necesita para obtener ValidatorFactory (o Validator sí mismo) a través de LocalValidatorFactoryBean en lugar de Validation.buildDefaultValidatorFactory(), como se describe en el referencia.

@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: Pero tal vez la mejor manera de hacerlo es utilizar la validación automática de Spring MVC con la anotación @Valid:

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

Esto también requiere <mvc:annotation-driven/> en el config.

Otros consejos

En lugar de crear un nuevo validador, usted tiene que Autowire o inyectarla al controlador. No se está creando el NPE del servicio no se está inyectando como su validador / gestionado por la primavera.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top