質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.13%

spring boot のフォーム用アノテーションにメソッド名を指定をする方法

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 4,636

yukidaruman

score 12

現在、spring boot 1.2.1 にて入力画面を作成しているのですが、
1画面内に、検索ボタンと登録ボタンがあり、いずれを押下しても
アノテーションでのチェックを行いたいです。

ただ、1つのフォームを使用しているため、いずれかのアクションを起こすと
検索用の項目と、登録用の項目のどちらもアノテーションチェックの結果が
BindingResultに格納されてきてしまう状況です。

フォームでのアノテーションを使用する際に「どの処理でのみ使用する」という指定は
可能なのでしょうか?
(SAStrutsの検証用アノテーションでいうところのtarget要素のようなもの)
調べてみましたが、そのような要素を見つけることができませんでした。

もし存在しないなら、フォームを別にするか、コントローラ側でチェックするしか手はないのでしょうか。

よろしくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

Validation の groups属性を使うと質問の内容と同等のことができるかと思います

以下のサンプルコードのようにすると、
1つのフォームクラスでもクリックされたボタンに応じてチェック処理を切り替えることができます

こんな感じで1つのフォーム内に複数ボタンがあるとします

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout">
<body>
<form th:action="@{/test}" th:object="${testForm}" method="post">
    <input type="text" th:field="*{param1}" name="param1" />
    <input type="text" th:field="*{param2}" name="param2" />
    <input type="text" th:field="*{param3}" name="param3" />
    <button id="action1" name='action1' value='action1' type="submit" >Action1</button>
    <button id="action2" name='action2' value='action2' type="submit" >Action2</button>
    <button id="action2" name='action3' value='action3' type="submit" >Action3</button>
</form>
</body>
</html>

まず、Form クラス内に実施するバリデーションを区別するためのインターフェースを用意します
-ValidationAction1 ※action1 のボタンで実施するバリデーションのグループ
-ValidationAction2 ※action2 のボタンで実施するバリデーションのグループ
-ValidationAll ※ValidationAction1、ValidationAction2の両方を行うグループ
※このインターフェースはForm クラスの外で定義しても同じです

そして、各バリデーションのアノテーションの引数 groups で、バリデーションのグループを指定します

public class TestForm implements Serializable {
    private static final long serialVersionUID = 1L;

    public interface ValidationAction1 {}

    public interface ValidationAction2 {}

    @GroupSequence({ValidationAction1.class, ValidationAction2.class})
    public interface ValidationAll {}

    @NotBlank(groups = {ValidationAction1.class})
    private String    param1;

    @NotBlank(groups = {ValidationAction2.class})
    private String    param2;

    @NotBlank
    private String    param3;


// 以下、getter & setter

}

コントローラー側ではどのグループのバリデーションを実行したフォームを受け取るかを指定します

例えば以下のように、クリックされたボタンに対応するアクションをそれぞれ用意します
そして、各アクションで受け取る Form オブジェクトに対して、@Validated の引数に実施するバリデーションのグループを指定します

そうすると、@Validatedでしていしたグループのバリデーションだけが実行されます
groups を指定しなかったバリデーションは Default に属するので注意してください
Default.class を付けないと groups なしのバリデーションは無視されます

@RequestMapping(method = RequestMethod.POST, value = "", params = {"action1"})
    public String action1(@Validated({TestForm.ValidationAction1.class, Default.class}) TestForm testForm, Errors errors)
        throws Throwable {
        // action1 の処理
        return "test";
    }

    @RequestMapping(method = RequestMethod.POST, value = "", params = {"action2"})
    public String action2(@Validated({TestForm.ValidationAction2.class, Default.class}) TestForm testForm, Errors errors)
        throws Throwable {
        // action2 の処理
        return "test";
    }

    @RequestMapping(method = RequestMethod.POST, value = "", params = {"action3"})
    public String action3(@Validated({TestForm.ValidationAll.class, Default.class}) TestForm testForm, Errors errors)
        throws Throwable {
        // action3 の処理
        return "test";
    }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/06 16:08

    Chanmoroさん、回答ありがとうございます!
    気付くのが遅れました。すいません。

    丁寧に注意点も書いていただき、サンプルソースまであったので
    ばっちり問題なく理解できました!
    自分の環境でも同じようにコーディングし、うまくいくことを確認しました。

    springBootは日本語の本も少なく、ネットも英語が多くてうまく答えを見つけることができずにとても困っていました。
    本当に助かりました。ありがとうございました!

    (関係ないですがspringBootってデフォルトのアノテーション少ないですね・・・)

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.13%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる