📚
SpringBootの相関チェック
はじめに
ホットペッパーAPIを使ってグルメサイトを作っているのだが、
検索条件を最低でも一つ入力しなければならない。
Formクラスの各フィールドに@NotNull
などの短項目チェックだと、2つ以上の項目がある場合
すべて入力しなければならない。
それだと簡単な検索ができない。。。
そこで相関項目チェックというものがあるのだが、今回はそれを使って複数まとめて項目チェックをする方法を実装していく。
この記事でわかること
- 相関チェックにより2つの項目が空である場合、エラーメッセージを表示する。
完成イメージ
住所エリア・キーワードの2つが空の状態で送信をした場合、
エラーメッセージ「どちらか一つを入力してください。」を出力させる。
前提
入力フォームの値はNameFormクラスで管理する。
入力フォーム
体裁がくずれているのはご容赦ください。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<body>
<div layout:fragment="sidebar" class="sidebar">
<!-- サイドメニューの内容 -->
<form th:action="@{/search}" method="post" th:object="${nameForm}">
<div>
<label for="address">住所エリア:</label>
<input type="text" id="address" name="address"/>
<div> </div>
</div>
<div>
<label for="keyword">キーワード:</label>
<input type="text" id="keyword" name="keyword"/>
<div> </div>
</div>
<div>
<label for="order">並び順:</label>
<select name="order">
<option value="1">名前順</option>
<option value="4">おすすめ順</option>
</select>
<div> </div>
</div>
<div style="text-align: left;">
<input type="submit" value="送信"/>
</div>
</form>
</div>
</body>
</html>
package com.example.demo.form;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
public class NameForm {
private String address;
private String keyword;
private String order;
}
手順
インターフェースValidatorの実装クラスを作成する
私はCHeckValidatorクラスとして作成。
入力値のチェックをするメソッドを実装する
@Component
public class CheckValidator implements Validator {
//チェックする入力フォームを記載する
@Override
public boolean supports(Class<?> clazz) {
// TODO 自動生成されたメソッド・スタブ
return NameForm.class.isAssignableFrom(clazz);
}
//入力値のチェックをする
@Override
public void validate(Object target, Errors errors) {
// TODO 自動生成されたメソッド・スタブ
NameForm form = (NameForm)target;
if(form.getAddress().isBlank() && form.getKeyword().isBlank()) {
errors.reject("com.example.demo.validator.CheckValidator.message");
}
}
}
エラーメッセージの作成
messages.prooerties
com.example.demo.CheckValidator.message = どちらか一つを入力してください。
ControllerでValidatorを設定する
@Autowired
CheckValidator checkValidator;
@InitBinder("nameForm")
public void initBinder(WebDataBinder webDataBinder) {
webDataBinder.addValidators(checkValidator);
}
@GetMapping("name")
public String getName(Model model,NameForm nameForm) throws IOException {
return "home";
}
//RequestParamをForm化したい
@PostMapping("search")
public String postName(@Validated NameForm nameForm, BindingResult bindingResult, Model model) throws IOException {
postNameの処理・・・
フォームバリデーションの結果を表示する属性を追加する
<div th:if="${#fields.hasErrors()}" th:errors="${nameForm}"></div>
を追加。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<body>
<div layout:fragment="sidebar" class="sidebar">
<!-- サイドメニューの内容 -->
<form th:action="@{/search}" method="post" th:object="${nameForm}">
<!-- バリテーションエラー追加 -->
<div th:if="${#fields.hasErrors()}" th:errors="${nameForm}"></div>
<div>
<label for="address">住所エリア:</label>
<input type="text" id="address" name="address"/>
<div> </div>
</div>
<div>
<label for="keyword">キーワード:</label>
<input type="text" id="keyword" name="keyword"/>
<div> </div>
</div>
<div>
<label for="order">並び順:</label>
<select name="order">
<option value="1">名前順</option>
<option value="4">おすすめ順</option>
</select>
<div> </div>
</div>
<div style="text-align: left;">
<input type="submit" value="送信"/>
</div>
</form>
</div>
</body>
</html>
実際に実行してみる
できてますね。
参考サイト
Discussion