spring
Spring JSR 303 Bean検証
サーチ…
前書き
SpringにはJSR303 Bean検証サポートがあります。これを使用して入力Beanの検証を行うことができます。 JSR303を使用したビジネスロジックからの個別の検証ロジック。
JSR303 Springのアノテーションベースのバリデーション例
JSR 303実装をクラスパスに追加します。人気のあるものは、HibernateのHibernateバリデータです。
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
</dependency>
システムにユーザーを作成するための残りのAPIがあるとします
@RequestMapping(value="/registeruser", method=RequestMethod.POST)
public String registerUser(User user);
入力jsonサンプルは以下のようになります
{"username" : "[email protected]", "password" : "password1", "password2":"password1"}
User.java
public class User {
private String username;
private String password;
private String password2;
getXXX and setXXX
}
JSR 303の検証は、以下のようにユーザークラスに定義できます。
public class User {
@NotEmpty
@Size(min=5)
@Email
private String username;
@NotEmpty
private String password;
@NotEmpty
private String password2;
}
また、パスワードとパスワード2(パスワードの確認)のようなビジネスバリデーターを同じにする必要があるかもしれません。これは以下のようにカスタムバリデーターを追加することができます。データフィールドに注釈を付けるためのカスタムアノテーションを作成します。
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PasswordValidator.class)
public @interface GoodPassword {
String message() default "Passwords wont match.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
検証ロジックを適用するためのValidatorクラスを記述します。
public class PastValidator implements ConstraintValidator<GoodPassword, User> {
@Override
public void initialize(GoodPassword annotation) {}
@Override
public boolean isValid(User user, ConstraintValidatorContext context) {
return user.getPassword().equals(user.getPassword2());
}
}
この検証をユーザークラスに追加する
@GoodPassword
public class User {
@NotEmpty
@Size(min=5)
@Email
private String username;
@NotEmpty
private String password;
@NotEmpty
private String password2;
}
@ValidはSpringの検証をトリガします。 BindingResultは、検証後にエラーのリストを持つSpringによって挿入されたオブジェクトです。
public String registerUser(@Valid User user, BindingResult result);
JSR 303アノテーションには、カスタムメッセージを提供するために使用できるメッセージ属性があります。
@GoodPassword
public class User {
@NotEmpty(message="Username Cant be empty")
@Size(min=5, message="Username cant be les than 5 chars")
@Email(message="Should be in email format")
private String username;
@NotEmpty(message="Password cant be empty")
private String password;
@NotEmpty(message="Password2 cant be empty")
private String password2;
}
Spring JSR 303 Validation - エラーメッセージのカスタマイズ
検証アノテーションを持つシンプルなクラスがあるとします
public class UserDTO {
@NotEmpty
private String name;
@Min(18)
private int age;
//getters/setters
}
UserDTOの有効性をチェックするコントローラ。
@RestController
public class ValidationController {
@RequestMapping(value = "/validate", method = RequestMethod.POST)
public ResponseEntity<String> check(@Valid @RequestBody UserDTO userDTO,
BindingResult bindingResult) {
return new ResponseEntity<>("ok" , HttpStatus.OK);
}
}
そして、テスト。
@Test
public void testValid() throws Exception {
TestRestTemplate template = new TestRestTemplate();
String url = base + contextPath + "/validate";
Map<String, Object> params = new HashMap<>();
params.put("name", "");
params.put("age", "10");
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Content-Type", "application/json");
HttpEntity<Map<String, Object>> request = new HttpEntity<>(params, headers);
String res = template.postForObject(url, request, String.class);
assertThat(res, equalTo("ok"));
}
名前と年齢の両方が無効なので、BindingResultには2つの検証エラーがあります。それぞれにはコードの配列があります。
最小チェックのコード
0 = "Min.userDTO.age"
1 = "Min.age"
2 = "Min.int"
3 = "Min"
NotEmptyチェック
0 = "NotEmpty.userDTO.name"
1 = "NotEmpty.name"
2 = "NotEmpty.java.lang.String"
3 = "NotEmpty"
デフォルトのメッセージを置き換えるcustom.propertiesファイルを追加しましょう。
@SpringBootApplication
@Configuration
public class DemoApplication {
@Bean(name = "messageSource")
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource bean = new ReloadableResourceBundleMessageSource();
bean.setBasename("classpath:custom");
bean.setDefaultEncoding("UTF-8");
return bean;
}
@Bean(name = "validator")
public LocalValidatorFactoryBean validator() {
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
bean.setValidationMessageSource(messageSource());
return bean;
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
custom.propertiesファイルに行を追加すると
NotEmpty=The field must not be empty!
エラーの新しい値が表示されます。メッセージバリデーターを解決するには、最初からコードを探し、適切なメッセージを探します。
したがって、 @NotEmpty
アノテーションが使用されているすべてのケースで.propertiesファイルにNotEmpty
キーを定義すると、メッセージが適用されます。
メッセージを定義すると
Min.int=Some custom message here.
整数値にminチェックを適用するすべての注釈は、新しく定義されたメッセージを使用します。
検証エラーメッセージをローカライズする必要がある場合は、同じロジックを適用できます。
ネストされたPOJOを検証するための@有効な使用法
検証する必要があるPOJOクラスのユーザーがいるとします。
public class User {
@NotEmpty
@Size(min=5)
@Email
private String email;
}
ユーザーインスタンスを検証するコントローラメソッド
public String registerUser(@Valid User user, BindingResult result);
検証する必要のあるPOJOネストされたPOJOアドレスをユーザーに拡張しましょう。
public class Address {
@NotEmpty
@Size(min=2, max=3)
private String countryCode;
}
ネストされたPOJOの検証を実行するために、アドレスフィールドに@Valid
アノテーションを追加するだけです。
public class User {
@NotEmpty
@Size(min=5)
@Email
private String email;
@Valid
private Address address;
}