SlideShare a Scribd company logo
1 of 31
Download to read offline
Javaでのバリデーション
〜Bean Validation篇〜
2014/12/04 Validation Night at Line
@eiryu
なにをやっているのか
● Twitter @eiryu
○ http://eiryu.com
● 仕事
○ インフラ・情シス
● バッググラウンド
○ Webアプリケーションエンジニア
■ Java
● Spring Framework
■ Groovy
■ JavaScript
■ PostgreSQL
なにをやっているのか
なぜやるのか
● 人間なのでヒューマンエラーは付きもの
● バリデーションされてなかったことによる壊れた
ユーザーデータはマーケティングにも生かせな
い
○ 男性で妊娠している等
● Webアプリケーションの場合、最悪ユーザー情
報が漏洩したり、操作されたりする
どうやってやっているのか
● Bean Validationを利用
● Webアプリケーションのコントローラでユーザー
入力をチェック
● 単体テスト(JUnit)で想定しうる不正な入力のテ
スト
※フレームワークはSpring Bootを利用
こんなことやります
Bean Validationで(ry
以上、Wantedly四段活用でした!
Bean Validationとは
“JavaBeansのバリデーション(値の検証)のため
のメタデータモデルとAPIを定めたJavaのソフト
ウェアフレームワーク”
Wikipedia
http://beanvalidation.org/
Bean Validationの沿革
2009 Bean Validation 1.0(JSR 303)
2013 Bean Validation 1.1(JSR 349)
JSRとは
Java Specification Requestsの略。日本語だと、
Java仕様要望。個人的にはJava版のRFCと捉え
ている。
何がうれしいのか
● あらかじめよく使う制約(チェック)が用意されて
いる
○ Constraintsと呼ぶ
● ユーザーの入力を受け取るJavaBeans
(POJO)にアノテーションで記載するため、
POJOに対してテストが書ける
○ コントローラのメソッド内でチェックしているとリクエストを
エミュレートするテストを書かなければならない
Constraintsの例
● @NotNull
○ nullでないこと
● @Pattern
○ 指定した正規表現にマッチすること
● @Size
○ 文字列等のサイズが指定した範囲であること
● @AssertTrue
○ trueであること
● @Future
○ JVMの現在日時より未来であること
packageはjavax.validation.constraints
ここで一般的なバリデーションの話に戻る
と。。
バリデーションの種類
● 単項目チェック
● 相関チェック
単項目チェック
● 1つの項目に対するチェック
● 例
○ ユーザー登録で名前の入力は必須だが、入力されてい
るか?
相関チェック
● 2つ以上の項目にまたがるチェック
● 例
○ 性別で男性を選択しているのに、妊婦の項目にチェック
していないか?
コード例
コード例
以下のようなフィールドを持つUserFormがあると
する
● 名前(name)
● 性別(sex)
● 妊娠しているか(pregnant)
コード例 単項目チェック
@NotNull(message = "性別がぬるぽ")
private Sex sex;
コード例 単項目チェック
● フィールドまたはそのgetterにConstraintsを付
与
コード例 相関チェック
@AssertTrue(message = "男性なのに妊娠してるって言ってる。。")
public boolean isValidPregnant() {
// 性別が入力されていない時は、そちらで引っかかるのでバリデーショ
ンしない
if (sex == null) {
return true;
}
// 妊娠していると選択している人が女性であることをチェック
if (pregnant) {
return Sex.FEMALE == sex;
}
return true;
}
コード例 相関チェック
● メソッドを定義してそこにアノテーションを付与
● 個人的には@AssertTrueのみ利用すれば良い
と思う
○ Bean ValidationのValidatorのお作法的に、isValidでバ
リデーションOKならばtrueを返すようになっている。その
流れに沿った方が分かりやすい
コード例 単体テスト
(特定プロパティのみのバリデーション)
private Validator validator =
Validation.buildDefaultValidatorFactory().getValidator();
@Test
public void validateName_正常系() {
UserForm userForm = new UserForm();
userForm.setName("eiryu");
Set<ConstraintViolation<UserForm>> violations =
validator.validateProperty(userForm, "name");
LOGGER.info("violations: " + violations);
assertThat(violations, hasSize(0));
}
コード例 単体テスト
(JavaBeans全体のバリデーション)
private Validator validator =
Validation.buildDefaultValidatorFactory().getValidator();
@Test
public void validate_正常系() {
UserForm userForm = new UserForm();
userForm.setName("eiryu");
userForm.setSex(Sex.MALE);
userForm.setPregnant(false);
Set<ConstraintViolation<UserForm>> violations =
validator.validate(userForm);
LOGGER.info("violations: " + violations);
assertThat(violations, hasSize(0));
}
コード例 Webアプリケーション
(Spring Bootのコントローラ)
@RequestMapping("registor")
public String registor(
@Valid UserForm userForm, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
LOGGER.warn("bindingResult: " + bindingResult);
return "index";
}
// some process..
return "redirect:/complete";
}
気にすべきポイント・TIPS
気にすべきポイント・TIPS
(バリデーションの順番)
● 普通に使うと、バリデーションが行われる順番はラ
ンダム
○ Webアプリケーションでメッセージを上部に列挙するよう
な場合に注意
○ 相関チェックでは、関係するフィールドが単項目チェック
済みでないことに注意して実装する必要がある
気にすべきポイント・TIPS
(バリデーションの順番)
● Group、 Group sequence という仕組みを使うとバ
リデーションの順番を制御することが出来る
○ JSRのSpecの例では、バリデーションで非常に重い処
理があって、それは他のバリデーションがOKだった時の
み実行する、というもの
○ 他に想定出来るのは、同時に2つ以上エラーになってい
るのに1つずつエラーメッセージ出すとか?
気にすべきポイント・TIPS
(メッセージ)
メッセージはプロパティファイルに外だし可能。ロケールごとの
ファイルを用意すればi18n対応も可能
● ValidationMessages.properties
● ValidationMessages_ja_JP.properties
プロパティファイルのエンコーディングはISO-8859-1で作成す
ること(昭和か!)
● IDEの自動変換かnative2ascii(昭和か!)で頑張りましょう
@NotNull(message = "{NotNull.sex}")
private Sex sex;
気にすべきポイント・TIPS
(その他)
● JavaBeansの中にJavaBeansがあるような
ケースでは、そのフィールドに対して@Validアノ
テーションを付与すれば再帰的にバリデーショ
ンされる
public class UserForm {
...
@Valid
private Address address;
...
}
ご清聴ありがとうございました
参考文献
● http://beanvalidation.org/
● http://yamkazu.hatenablog.
com/entry/20110206/1296985545

More Related Content

What's hot

オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメ
Yoji Kanno
 
AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05
AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05
AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05
都元ダイスケ Miyamoto
 

What's hot (20)

ビッグデータ処理データベースの全体像と使い分け
ビッグデータ処理データベースの全体像と使い分けビッグデータ処理データベースの全体像と使い分け
ビッグデータ処理データベースの全体像と使い分け
 
PostgreSQLモニタリング機能の現状とこれから(Open Developers Conference 2020 Online 発表資料)
PostgreSQLモニタリング機能の現状とこれから(Open Developers Conference 2020 Online 発表資料)PostgreSQLモニタリング機能の現状とこれから(Open Developers Conference 2020 Online 発表資料)
PostgreSQLモニタリング機能の現状とこれから(Open Developers Conference 2020 Online 発表資料)
 
ポスト・ラムダアーキテクチャの切り札? Apache Hudi(NTTデータ テクノロジーカンファレンス 2020 発表資料)
ポスト・ラムダアーキテクチャの切り札? Apache Hudi(NTTデータ テクノロジーカンファレンス 2020 発表資料)ポスト・ラムダアーキテクチャの切り札? Apache Hudi(NTTデータ テクノロジーカンファレンス 2020 発表資料)
ポスト・ラムダアーキテクチャの切り札? Apache Hudi(NTTデータ テクノロジーカンファレンス 2020 発表資料)
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
 
Azure Search 大全
Azure Search 大全Azure Search 大全
Azure Search 大全
 
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3 データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
 
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計
 
ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門
 
オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメ
 
怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション
 
SpringBootTest入門
SpringBootTest入門SpringBootTest入門
SpringBootTest入門
 
マルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのことマルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのこと
 
マイクロサービスにおけるテスト自動化 with Karate
マイクロサービスにおけるテスト自動化 with Karateマイクロサービスにおけるテスト自動化 with Karate
マイクロサービスにおけるテスト自動化 with Karate
 
Fluentd, Digdag, Embulkを用いたデータ分析基盤の始め方
Fluentd, Digdag, Embulkを用いたデータ分析基盤の始め方Fluentd, Digdag, Embulkを用いたデータ分析基盤の始め方
Fluentd, Digdag, Embulkを用いたデータ分析基盤の始め方
 
開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)
 
GraphQLのsubscriptionで出来ること
GraphQLのsubscriptionで出来ることGraphQLのsubscriptionで出来ること
GraphQLのsubscriptionで出来ること
 
[AWS EXpert Online for JAWS-UG 18] 見せてやるよ、Step Functions の本気ってやつをな
[AWS EXpert Online for JAWS-UG 18] 見せてやるよ、Step Functions の本気ってやつをな[AWS EXpert Online for JAWS-UG 18] 見せてやるよ、Step Functions の本気ってやつをな
[AWS EXpert Online for JAWS-UG 18] 見せてやるよ、Step Functions の本気ってやつをな
 
失敗事例で学ぶ負荷試験
失敗事例で学ぶ負荷試験失敗事例で学ぶ負荷試験
失敗事例で学ぶ負荷試験
 
ドメイン駆動設計のためのオブジェクト指向入門
ドメイン駆動設計のためのオブジェクト指向入門ドメイン駆動設計のためのオブジェクト指向入門
ドメイン駆動設計のためのオブジェクト指向入門
 
AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05
AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05
AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05
 

More from eiryu (8)

Introducing thymeleaf
Introducing thymeleafIntroducing thymeleaf
Introducing thymeleaf
 
Ninja framework使ってみた
Ninja framework使ってみたNinja framework使ってみた
Ninja framework使ってみた
 
JMeter小話
JMeter小話JMeter小話
JMeter小話
 
Thymeleafのすすめ
ThymeleafのすすめThymeleafのすすめ
Thymeleafのすすめ
 
最近のJavaでの開発について
最近のJavaでの開発について最近のJavaでの開発について
最近のJavaでの開発について
 
Thymeleafでハマったこと
ThymeleafでハマったことThymeleafでハマったこと
Thymeleafでハマったこと
 
TwFavView
TwFavViewTwFavView
TwFavView
 
Spring小話
Spring小話Spring小話
Spring小話
 

Javaでのバリデーション 〜Bean Validation篇〜