Java 記事

【Spring】オリジナルのバリデーションを作る【Java】

記事のターゲット

  • Springでアノテーション以外の文字チェック等を実装したい人

背景

Formにアノテーションをつける以外(二重チェック等)のバリデーションの方法をメモしておきます。今回はBean ValidationではなくSpring Validatorを使用します。

今回参考にしているのは以下の本です。Springをいじるうえではこの本さえあればいいと思います。

方法

 まず前提として次画面に渡すForm内にエラー保持用の変数を作ります。

public class SessionForm {

    private CheckForm checkForm;
    //エラー出力用変数
    private String error1;

    private String error2;
    //セッター等省略
}

次にバリデーション専用のクラスを作成していきます。

フォルダの場所はapplicationと同じ階層に置くと良いです。

@Component
                             //インターフェース実装
public class CheckValidation implements Validator {
    //Checkにヘルパーを使う場合は注入
    @Autowired
    Helper helper;

    @Override
    public boolean supports(Class<?> clazz) {
        //チェックしたいFormを入れる(セッションアトリビュートしたクラス)
        //isAssignableFromは継承したクラスもすべて
        return SessionForm.class.isAssignableFrom(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        //対象クラスをいったん作成
        SessionForm form = (SessionForm) target;
        //form.checkForm.~とすることで入れ子の要素も使用可能
        if (条件式) {
                errors.rejectValue(
                       //フォームに指定した変数
                       "error1",
                       //別のファイルにメッセージ定義してない場合Null
                        null, 
                       "出力したいメッセージ");
            }

        //別のチェックをする
        if (条件式) {
                errors.rejectValue(
                        "error2", 
                         null, 
                        "出力したいメッセージ");
                }
}

チェック対象のクラスを指定して条件式に合わなかった場合エラーにメッセージと一緒に格納します。

あとはController部分で作ったバリデートを使用していきます。

@Controller
@SessionAttributes(names = "sessionForm")
public class ExampleController {
    //Key設定用
    private static final String FORM_NAME = "sessionForm";

    //自作バリデーションクラスをインジェクション
    @Autowired
    CheckValidation checkValidation;

    //WebDataBinderに追加
    @InitBinder("sessionForm")
    public void initBinder(WebDataBinder binder) {
        binder.addValidators(checkValidation);
    }

    //メソッドにつけるモデアトは呼び出し前にモデルに場所を追加してくれる
    @ModelAttribute(value = "sessionForm")
    public SessionForm sessionForm() {
        return new SessionForm();
    }

//a
@RequestMapping(path="リダイレクトに入れたパス", method=RequestMethod.GET)
    public String putInformation(@ModelAttribute(FORM_NAME) SessionForm session, BindingResult result,ModelMap model) {

        String key = BindingResult.MODEL_KEY_PREFIX + FORM_NAME;
        //リダイレクト時にモデルにエラーがあれば
        if(model.containsKey("errors")) {
            //Keyに設定したフォームにマップ形式でエラー格納
            model.addAttribute(key, model.get("errors"));
            model.addAttribute("sessionForm" , session);
            return "遷移したいJSP等";
        }
        //他省略
}

//b
@RequestMapping(path="入力確認画面等", method=RequestMethod.POST)
    public String confirmInfomation(@Validated SessionForm session, BindingResult result, Model model, RedirectAttributes ra)throws Exception {

            if(result.hasErrors()) {
            ra.addFlashAttribute("errors", result);
            //入力画面へリダイレクト
            return "redirect:/{呼び出したいコントローラのパスへ}";
        }
        //他省略
}

まずフォームにエラー用変数作成し、バリデータでエラーが出たらエラー用変数に情報を格納する。

コントローラでWebDataBinderにバリデータを追加することによりBeanValidation呼び 出し、

その後に追加したバリデータが呼び出され自作のチェックが行われる。Autowiredも忘れない。

BindingResultにエラーがあればその情報を保持したままリダイレクト(入力の確認画面へ遷移する前の部分等でチェック)。メソッドの流れはa→b→aの順。

リダイレクト先のメソッドでエラーの有無で分岐し、あればエラー情報をモデルに格納しJSPと共有する。JSPでformタグのerrorsを使用し、パスとセッション用フォームの変数を一致させエラーメッセージを出力。

まとめ

今回はアノテーションを使った楽なバリデートではなく、オリジナルのチェックを実装してみました。

これを使えるようになると論理チェック等も好きに実装できるのでぜひ試してみてください。

スポンサーリンク

-Java, 記事
-, , , , , ,

© 2022 ビギテック