SlideShare a Scribd company logo
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

PDF
Javaのログ出力: 道具と考え方
PDF
これからSpringを使う開発者が知っておくべきこと
PDF
入社1年目のプログラミング初心者がSpringを学ぶための手引き
PDF
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
PDF
Spring Day 2016 - Web API アクセス制御の最適解
PDF
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
PDF
イミュータブルデータモデルの極意
Javaのログ出力: 道具と考え方
これからSpringを使う開発者が知っておくべきこと
入社1年目のプログラミング初心者がSpringを学ぶための手引き
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
Spring Day 2016 - Web API アクセス制御の最適解
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
イミュータブルデータモデルの極意

What's hot (20)

PDF
PlaySQLAlchemy: SQLAlchemy入門
PPTX
MicrometerとPrometheusによる LINEファミリーアプリのモニタリング
PDF
オブジェクト指向の設計と実装の学び方のコツ
PDF
【TECH×GAME COLLEGE#32】ゼロからリアルタイムサーバーを作るまで
PPTX
RLSを用いたマルチテナント実装 for Django
PDF
さいきんの InnoDB Adaptive Flushing (仮)
PDF
怖くないSpring Bootのオートコンフィグレーション
PDF
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
PPTX
SQLチューニング入門 入門編
PDF
文字コードに起因する脆弱性とその対策(増補版)
PDF
アクセスプラン(実行計画)の読み方入門
PDF
Spring bootでweb バリデート編
PDF
SQLアンチパターン - ジェイウォーク
PPTX
MongoDBが遅いときの切り分け方法
PDF
実践 NestJS
PPTX
ReactでuseEffect()を減らしたい話
PDF
クラウド時代だからSpring-Retryフレームワーク
PDF
「GraphDB徹底入門」〜構造や仕組み理解から使いどころ・種々のGraphDBの比較まで幅広く〜
PDF
トランザクションの並行処理制御
PDF
SQL大量発行処理をいかにして高速化するか
PlaySQLAlchemy: SQLAlchemy入門
MicrometerとPrometheusによる LINEファミリーアプリのモニタリング
オブジェクト指向の設計と実装の学び方のコツ
【TECH×GAME COLLEGE#32】ゼロからリアルタイムサーバーを作るまで
RLSを用いたマルチテナント実装 for Django
さいきんの InnoDB Adaptive Flushing (仮)
怖くないSpring Bootのオートコンフィグレーション
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
SQLチューニング入門 入門編
文字コードに起因する脆弱性とその対策(増補版)
アクセスプラン(実行計画)の読み方入門
Spring bootでweb バリデート編
SQLアンチパターン - ジェイウォーク
MongoDBが遅いときの切り分け方法
実践 NestJS
ReactでuseEffect()を減らしたい話
クラウド時代だからSpring-Retryフレームワーク
「GraphDB徹底入門」〜構造や仕組み理解から使いどころ・種々のGraphDBの比較まで幅広く〜
トランザクションの並行処理制御
SQL大量発行処理をいかにして高速化するか
Ad

More from eiryu (8)

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

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