javax.validation.constraints
、@Size
などの@NotNull
からの注釈を使用するには、どのような構成が必要ですか?ここに私のコードがあります:
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class Person {
@NotNull
private String id;
@Size(max = 3)
private String name;
private int age;
public Person(String id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
}
別のクラスで使用しようとすると、検証が機能しません(つまり、オブジェクトはエラーなしで作成されます):
Person P = new Person(null, "Richard3", 8229));
なぜこれはid
とname
の制約を適用しないのですか?他に何をする必要がありますか?
JSR-303 Bean検証をSpringで機能させるには、次のものが必要です。
<mvc:annotation-driven />
validation-api-1.0.0.GA.jar
(既にお持ちのようです)hibernate-validator-4.1.0.Final.jar
@Valid
注釈を付けてから、メソッドシグネチャにBindingResult
を含めてエラーをキャプチャします。例:
@RequestMapping("handler.do")
public String myHandler(@Valid @ModelAttribute("form") SomeFormBean myForm, BindingResult result, Model model) {
if(result.hasErrors()) {
...your error handling...
} else {
...your non-error handling....
}
}
Validatorを使用して、クラスが有効かどうかを確認する必要があります。
Person person = ....;
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
Set<ConstraintViolation<Person>> violations = validator.validate(person);
次に、違反セットを繰り返し、違反を見つけることができます。
Validatorを呼び出す必要があります検証する場合はエンティティです。その後、ConstraintViolationExceptionのセットを取得します。これは基本的にエンティティのどのフィールドに制約違反があり、正確に何であったかを表示です。エンティティを検証する予定のコードの一部を共有することもできます。
頻繁に使用される手法は、トランザクション中に複数のデータ変更を使用する場合に@PrePersistで検証を行い、トランザクションをロールバックするか、検証例外を取得したときに他のアクションを実行することです。
コードは次のようになります。
@PrePersist
public void prePersist(SomeEntity someEntity){
Validator validator = Validation.buildDefaultValidatorFactory.getValidator();
Set<ConstraintViolation<SomeEntity>> = validator.validate(someEntity);
//do stuff with them, like notify client what was the wrong field, log them, or, if empty, be happy
}
また、@NonNull
をlombokライブラリと一緒に使用することもできます、少なくともfor @NotNull
シナリオ。詳細: https://projectlombok.org/api/lombok/NonNull.html
私の場合、呼び出されていないカスタムクラスレベルの制約がありました。
@CustomValidation // not called
public class MyClass {
@Lob
@Column(nullable = false)
private String name;
}
クラスまたはフィールドレベルの制約をカスタムクラスまたは標準クラスに追加するとすぐに、クラスレベルの制約が機能し始めました。
@CustomValidation // now it works. super.
public class MyClass {
@Lob
@Column(nullable = false)
@NotBlank // adding this made @CustomValidation start working
private String name;
}
私にはバグのある行動のようですが、回避するには十分簡単です
数年後にここに来て、 atrain の 上記のコメント のおかげで修正できました。私の場合、[〜#〜] api [〜#〜]に@Valid
がありませんでした。 @Size
の注釈が付けられています。問題を解決しました。
私は、not@Valid
や@NotBlank
などの追加の注釈を、@Size
で注釈された変数に追加する必要がありました。変数と私がAPIで言及したこと...
Pojoクラス:
...
@Size(min = MIN_LENGTH, max = MAX_LENGTH);
private String exampleVar;
...
APIクラス:
...
public void exampleApiCall(@RequestBody @Valid PojoObject pojoObject){
...
}
感謝と歓声
メソッドパラメータには、Objects.requireNonNull()を次のように使用できます。test(String str) { Objects.requireNonNull(str); }
ただし、これは実行時にのみチェックされ、nullの場合はNPEをスローします。これは前提条件チェックのようなものです。しかし、それはあなたが探しているものかもしれません。
したがって、サービスインターフェイスの@Validは、そのオブジェクトに対してのみ機能します。 ServiceRequestオブジェクトの階層内にさらに検証がある場合、明示的に検証をトリガーすることができます。だからこれは私がそれをやった方法です:
public class ServiceRequestValidator {
private static Validator validator;
@PostConstruct
public void init(){
validator = Validation.buildDefaultValidatorFactory().getValidator();
}
public static <T> void validate(T t){
Set<ConstraintViolation<T>> errors = validator.validate(t);
if(CollectionUtils.isNotEmpty(errors)){
throw new ConstraintViolationException(errors);
}
}
}
そのオブジェクトの検証をトリガーする場合は、オブジェクトレベルで次の注釈が必要です。
@Valid
@NotNull
@ Validを各メンバー変数に追加する必要があります。検証制約。
atrainからのすばらしい答えですが、例外をキャッチするためのより良い解決策は、独自のHandlerExceptionResolverとcatchを利用することです。
@Override
public ModelAndView resolveException(
HttpServletRequest aReq,
HttpServletResponse aRes,
Object aHandler,
Exception anExc
){
// ....
if(anExc instanceof MethodArgumentNotValidException) // do your handle error here
}
その後、ハンドラーを可能な限りクリーンに保つことができます。 myHandlerMethodのBindingResult、Model、SomeFormBeanはもう必要ありません。