サービスをバリデーターに自動化します
-
01-10-2019 - |
質問
この例は少し不自然です。無関係な詳細を削除し、私が抱えている問題に焦点を合わせるために簡略化しました。私はこのように見えるバリデーターを持っています:
@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);
}
}
私はこのように私のコントローラーからバリデーターを呼び出します:
@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);
}
しかし、私は取得し続けます NullPointerException
例外。私は私のバリデーターにブレークポイントを追加して、それを見ました usernameService
だった null
. 。なぜ自動車を飼っていないのですか?当初、私はそれが私がバリデーターに注釈を付けていなかったからだと思った @Component
, 、しかし、注釈を付けた後でも、私はまだ同じ問題を抱えています。 UsernameService
クラスにはすでに注釈が付けられています @Service
そして、そのコンストラクターが呼び出されていることを確認できます。
私は春が初めてなので、サービスをバリデーターに配線するのが大丈夫かどうかさえわかりません。私は何が間違っているのですか?
解決
春には、取得する必要があります ValidatorFactory
(また Validator
それ自体)経由 LocalValidatorFactoryBean
それ以外の Validation.buildDefaultValidatorFactory()
, 、説明されているように 参照.
@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"/>
編集: しかし、おそらくそれを行うためのより良い方法は、スプリングMVCの自動検証を使用することです @Valid
注釈:
@RequestMapping
public void checkUsername(Model model, @Valid User user, BindingResult result) {
if (result.hasErrors()) {
...
}
}
これにも必要です <mvc:annotation-driven/>
構成内。
他のヒント
新しいバリデーターを作成する代わりに、コントローラーに自動化または注入する必要があります。 NPE
ValidatorがSpringによって作成/管理されていないため、サービスが注入されていません。