Autowiring einen Dienst in einem Prüfer
-
01-10-2019 - |
Frage
Dieses Beispiel ist ein wenig gekünstelt; Ich habe es vereinfacht Fremd Details zu entfernen und das Problem konzentrieren sich auf das ich habe. Ich habe einen Validator, dass sieht wie folgt aus:
@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);
}
}
Ich nenne den Validator von meinem Controller wie folgt aus:
@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);
}
ich jedoch behalten NullPointerException
Ausnahme bekommen. Ich habe einen Haltepunkt in meinem Validator und sah, dass usernameService
war null
. Warum ist es nicht autowired bekommen? Anfangs dachte ich, es ist, weil ich nicht den Validator mit @Component
kommentiert hatte, aber ich habe immer noch das gleiche Problem, auch nachdem sie mit Anmerkungen versehen. Die UsernameService
Klasse bereits mit @Service
kommentiert worden und ich kann bestätigen, dass ihr Konstruktor aufgerufen zu werden.
Ich bin neu in Spring, so dass ich bin nicht einmal sicher, ob es in Ordnung ist, einen Dienst in einen Prüfer verdrahten. Was mache ich falsch?
Lösung
Im Frühjahr, müssen Sie ValidatorFactory
(oder Validator
selbst) über LocalValidatorFactoryBean
statt Validation.buildDefaultValidatorFactory()
zu erhalten, wie beschrieben in der Referenz .
@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: Aber vielleicht der bessere Weg, es zu tun ist, Spring MVC automatische Validierung mit @Valid
Annotation zu verwenden:
@RequestMapping
public void checkUsername(Model model, @Valid User user, BindingResult result) {
if (result.hasErrors()) {
...
}
}
Dies erfordert auch <mvc:annotation-driven/>
in der config.
Andere Tipps
Statt einen neuen Validator zu schaffen, müssen Sie autowire oder es an den Controller zu injizieren. Die NPE
aus dem Dienst nicht als Validierer injiziert wird, nicht durch Feder erstellt / verwaltet werden.