素敵なサムシングを独断と偏見で一方的に紹介するブログ(´・ω・`)

投稿日: 2019年9月14日
最終更新日:

【Play Framework2.7】自作のBeanValidatorのエラーメッセージをscalaテンプレートから取得出来ない場合の原因と対処方法【ConstraintValidator】

YouTubeも見てね♪

ねこじゃすり

created by Rinker
PEPPY(ペピイ)
¥3,850 (2025/01/05 12:56:12時点 Amazon調べ-詳細)

猫を魅了する魔法の装備品!

【最新機種】GoPro hero11 Black

created by Rinker
¥61,300 (2025/01/05 20:59:47時点 楽天市場調べ-詳細)

最新機種でVlogの思い出を撮影しよう!

ペヤング ソースやきそば 120g×18個

created by Rinker
ペヤング
¥3,280 (2025/01/05 12:33:38時点 Amazon調べ-詳細)

とりあえず保存食として買っておけば間違いなし!

レッドブル エナジードリンク 250ml×24本

created by Rinker
Red Bull(レッドブル)
¥4,000 (2025/01/05 12:33:39時点 Amazon調べ-詳細)

翼を授けよう!

ドラゴンクエスト メタリックモンスターズギャラリー メタルキング

created by Rinker
スクウェア・エニックス(SQUARE ENIX)
¥3,940 (2025/01/05 12:41:47時点 Amazon調べ-詳細)

みんな大好き経験値の塊をデスクに常備しておこう!

MOFT X 【新型 ミニマム版】 iPhone対応 スマホスタンド

Amazon一番人気のスマホスタンド!カード類も収納出来てかさ張らないのでオススメです!

サンディスク microSD 128GB

スマホからSwitchまで使える大容量MicroSDカード!

scalaテンプレートでバリデーションエラーを取ろうとするとエラーが発生する

とある案件にてPlayFramework2.7でWebシステムを開発している際に、バリデーションエラーを画面に表示しようと公式のように実装していたところ、以下のようなエラーが発生しました。

ログを見ただけではちょっとエラーがまだ特定出来ませんね。

まずはデバッグでソースを追いながら原因を特定して対応していこうと思います

手順

前提

今回は以下のような一般的な独自アノテーションによるバリデーションを行おうと思っています。

インタフェース

実装クラス

Formモデル

login.scala.html

HTMLについては今回の必要な部分だけ抜粋しておきます。

org.springframework.beans.AbstractNestablePropertyAccessorでエラー

デバッグでソースを追っていくと、怪しい部分がありました。

>org.springframework.beans.AbstractNestablePropertyAccessor.javaの620行目辺りのPropertyHandler ph = getLocalPropertyHandler(actualName);にてnullが帰って来ておりそのあとのハンドリングでthrow new NotReadablePropertyException(getRootClass(), this.nestedPath + propertyName);とされています。

getLocalPropertyHandler

では、getLocalPropertyHandlerメソッドでは何をやっているのでしょうか。

ざっくり言うと、LoginFormModel.javaに定義されているフィールド名をmap形式で持っており、引数で渡って来たpropertyNameの存在をチェックしていますね。

今回は、フィールドは定義せずgetterにアノテーションを付与してバリデーションを実現しています。

実際カスタムBeanValidator自体は正常に動いているので、そのあとのエラーメッセージのバインディングの部分でメソッドに対するBeanValidatorをサポートしていないようですね。

フィールドを定義する事で回避可能

取り急ぎ原因は分かりました。

解決するには、以下のように同名のフィールドを定義する事で正常に動くようになりました。

loginCheckフィールド自体はフォームからは飛んでくる値ではないので、かなり気持ち悪いですが一旦はこれで解決しました。

何かもっと良い方法や筆者の認識や使い方が間違っている等あればご指摘頂ければなと思いますorz

PlayFrameworkには別の方法でカスタムバリデーションを実装出来る

ちなみに、PlayFrameworkではアノテーションではなくvalidateメソッドの@Overrideによって実現する事も出来ます。

Sometimes you need more sophisticated validation processes. E.g. when a user signs up you want to check if his email address already exists in the database and if so validation should fail.

Because constraints support both runtime Dependency Injection and , we can easily create our own custom (class-level) constraint which gets a Database object injected – which we can use later in the validation process. Of course you can also inject other components like MessagesApi, JPAApi, etc.Java Forms – 2.7.x

しかし、個人的な意見としては使い勝手はいまいちなのと複雑なのであまり使いたくありません。。。

終わりに

以上のように、フレームワークのかなりコアな部分が原因でした。

割と致命的な挙動だと思うので、お困りの方がいましたら是非試してみてください♪

CATEGORIES & TAGS

IT