きり丸アドベントカレンダー2020の12記事目です。
画面の項目が必須項目なのか、数字のみ許容するのか、Email形式のみしか許容しないのかをサーバ側で検証する必要があります。この項目を検証することをバリデーションと言います。
基本的には画面側のJavaScriptでも検証すべきですが、javaScriptは開発者モードで無効化することもできたりするので、最終的にはサーバ側で検証したほうがいいです。
ゴール
- 画面項目をサーバでバリデーションする
環境
- Java
- 15
- org.springframework.boot:spring-boot-starter-validation
- 2.4.0
手順
バリデーション用ライブラリをインストール
2.3より前のバージョンは、spring-boot-starter-web
にバリデーション用ライブラリが含まれていましたが、2.3以降からライブラリが分かれてしまったため、spring-boot-starter-validation
を含める必要があります。
おそらく、最近SpringBootを最新にしている人はちょっとだけ引っかかるポイントです。
ファイル名:build.gradle
implementation 'org.springframework.boot:spring-boot-starter-validation'
DTOに制約を付与する
下記項目のidに関しては、空文字からintに変換できないので、一応そのままでも大丈夫です。IDは1~1000までしか採番したくない、という場合は@Min(1)@Max(1000)
を付与します。
今回の場合、他の項目が空文字だとデータとして意味が無いので、空文字を許容しない@NotNull
を付与します。
ファイル名:TodoDto.java
public class TodoDto { @Min(1) @Max(1000) @NotNull int id; @NotNull String userId; @NotNull String action; }
他にも色んなバリデーションをかけられます。次のJavadocから詳細を確認してみてください。
https://spring.pleiades.io/specifications/platform/8/apidocs/
SpringBoot自体には含まれてませんが、Hibernateを使用している場合の@CreditCardNumber
等のバリデーションは面白いですね。
ソースコードにバリデーションすることを明示する
パラメータのTodoDto
クラスに@Validated
を付与すると上記で設定した@NotNull
が有効になります。もし、これらのアノテーションを満たしていない場合はBadRequestとして返却されます。
@PostMapping(value="/", params="add") public String add(@Validated TodoDto model){ todoRepository.insert(model); return "redirect:/"; }
テストコードで確認する
ControllerのAddメソッドが呼ばれたときに、バリデーションを有効にしました。次のテストコードは、アノテーションを満たして正常処理されるパターンと、満たせずにBadRequestとして処理されるパターンを検証しています。
@Test void test_01() throws Exception { TodoDto expected = TodoDto.builder() .id(123) .userId("user") .action("actionする") .build(); mockMvc.perform(MockMvcRequestBuilders.post("/") .param("add", "add") .param("id", "123") .param("userId", "user") .param("action", "actionする") ) .andExpect(status().isFound()); Mockito.verify(todoRepository).insert(expected); } @Test void test_02() throws Exception { mockMvc.perform(MockMvcRequestBuilders.post("/") .param("add", "add") ) .andExpect(status().is4xxClientError()); }
ソースコード
アドベントカレンダー12日目。
github.com
終わりに
画面で入力されたデータを検証しないと、意図しないデータが含まれてしまい、修正が難しくなります。ですので、事前にバリデーションを多めに行っておくことが大事になります。
データを別システムが持っている場合、厳しすぎるバリデーションが問題になることもありますが…。単純なバリデーションならやっておくべきでしょう。
この記事がお役に立ちましたら、各種SNSでのシェアや、今後も情報発信しますのでフォローよろしくお願いします。
参考記事
敬称略。
リファレンス。 spring.pleiades.io
類似記事
きり丸アドベントカレンダー2020 adventar.org
きり丸のHerokuページ
https://kirimaru-todoapp.herokuapp.com/
13日目のアドベントカレンダーの記事 https://nainaistar.hatenablog.com/entry/2020/12/13/083000nainaistar.hatenablog.com