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

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

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

YouTubeも見てね♪

【最新機種】GoPro hero11 Black

created by Rinker
GoPro(ゴープロ)
¥62,000 (2024/03/15 19:06:06時点 Amazon調べ-詳細)

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

[ノースフェイス] THE NORTH FACE メンズ アウター マウンテンライトジャケット

created by Rinker
THE NORTH FACE(ザノースフェイス)
¥29,280 (2024/03/15 19:06:01時点 Amazon調べ-詳細)

防水暴風で耐久性抜群なので旅行で大活躍です!

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

created by Rinker
Red Bull(レッドブル)
¥4,080 (2024/03/15 19:03:47時点 Amazon調べ-詳細)

翼を授けよう!

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

created by Rinker
スクウェア・エニックス(SQUARE ENIX)
¥3,250 (2024/03/15 19:03:48時点 Amazon調べ-詳細)

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

Bauhutte ( バウヒュッテ ) 昇降式 L字デスク ブラック BHD-670H-BK

created by Rinker
Bauhutte(バウヒュッテ)
¥13,861 (2024/03/15 15:06:46時点 Amazon調べ-詳細)

メインデスクの横に置くのにぴったりなおしゃれな可動式ラック!

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

created by Rinker
MOFT
¥2,880 (2024/03/15 19:06:03時点 Amazon調べ-詳細)

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