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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Thymeleaf

Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

解決済

2回答

3852閲覧

Spring Bootで、画面入力値を加工する方法

Ajax2017

総合スコア7

Thymeleaf

Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

0グッド

0クリップ

投稿2017/12/03 14:22

###前提・実現したいこと
Spring Bootで、画面入力値を加工(大文字化等)したい。

###発生している問題・エラーメッセージ
・現在の状態
1.AOPでsetterに渡す文字列を事前に加工した。文字列は、StringBuiderを使用。
2.同時にバリデーションを掛けている。(@NotEmpty等)

・問題
1.は成功したが、2.が必ずエラーとなる。
しかし、form.getXxx()の返り値は大文字化された値が返される。

・聞きたいこと
(1)上記AOPとバリデーションの二律背反を回避することは、可能か?
(2)回避不可の場合、より簡単で、なるべくコードが分散しない方法はありますか?
AOPを止め、独自バリデーションで、文字列加工する方法を試行し、所期の結果を得られることを確認済みですが、全メンバーに付与するのが難点なので、よりよい方法があれば、ご教授いただきたい。

###該当のソースコード

Java

1@Controller 2@RequestMapping("/test01") 3public class Test01 { 4 @PostMapping() 5 public ModelAndView procPost(@Validated @ModelAttribute("contentsForm") Test01Form form, 6 BindingResult result, 7 ModelAndView mav) { 8 // form.getItem01()は、入力値が大文字変換された値が返される。 9 mav.setViewName("test01"); 10 return mav; 11 } 12} 13 14@Component 15@Data 16public class Test01Form { 17 // 必ずエラーとなる 18 @NotEmpty 19 StringBuilder item01; 20 21 @NotEmpty 22 StringBuilder item02; 23} 24 25 26@Aspect 27@Component 28public class TestAOP { 29 @Around("execution (* com.example.demo.*.setItem*(..))") 30 public void around(ProceedingJoinPoint pjp) { 31 // 入力値を大文字に変換する。 32 Object[] args = pjp.getArgs(); 33 StringBuilder sb = (StringBuilder) args[0]; 34 String val = sb.toString().toUpperCase(); 35 sb.delete(0, sb.length()); 36 sb.append(val); 37 args[0] = sb; 38 try { 39 pjp.proceed(args); 40 } catch (Throwable e) { 41 e.printStackTrace(); 42 } 43 } 44} 45

html

1 2 <form th:action="@{/test01}" th:method="post" th:object="${contentsForm}"> 3 <span>Item01:</span> 4 <input th:type="text" th:field="*{item01}" /> 5 <label th:if="${#fields.hasErrors('*{item01}')}" th:errors="*{item01}">×</label> 6 <br /> 7 <span>Item02:</span> 8 <input th:type="text" th:field="*{item02}" /> 9 <label th:if="${#fields.hasErrors('*{item02}')}" th:errors="*{item02}">×</label> 10 <br /> 11 <input th:type="submit" th:value="@{実行}" /> 12 </form> 13

###試したこと
eclipseで変数を調査した結果から、以下が原因と思われます。

フォームクラスは、AOPを適用したことで、ラッピングされており、メンバー変数は、ずべてnullであったが、内部に、元のフォームクラス(メンバー変数値は正常)を保持しており、form.getXxx()を実行すると、元のフォームクラスの値を返している。
しかし、バリデーションは、ラッピングクラスのメンバー変数を直接?参照してしまい、結果として、未入力と判断されていると思われる。

###補足情報(言語/FW/ツール等のバージョンなど)
Spring Bootバージョン 1.5.3

Test01#procPostで止めて、変数タブでformを選択した状態:

form Test01Form$$EnhancerBySpringCGLIB$$6956de2b (id=124)
Test01Form(item01=ABCDE, item02=2)
見た目では、正常に値が設定されているように見える。

formのツリーを開いた状態:

form Test01Form$$EnhancerBySpringCGLIB$$6956de2b (id=124)
CGLIB$BOUND false
CGLIB$CALLBACK_0 CglibAopProxy$DynamicAdvisedInterceptor (id=186)
CGLIB$CALLBACK_1 CglibAopProxy$StaticUnadvisedInterceptor (id=189)
CGLIB$CALLBACK_2 CglibAopProxy$SerializableNoOp (id=191)
CGLIB$CALLBACK_3 CglibAopProxy$StaticDispatcher (id=193)
CGLIB$CALLBACK_4 CglibAopProxy$AdvisedDispatcher (id=196)
CGLIB$CALLBACK_5 CglibAopProxy$EqualsInterceptor (id=199)
CGLIB$CALLBACK_6 CglibAopProxy$HashCodeInterceptor (id=201)
item01 null
item02 null
id=124はラッピングされたインスタンスと思われる。
そのメンバー変数(item01, item02)は、null。

さらに、CGLIB$CALLBACK_0等を、開いた状態:

targetSource SingletonTargetSource (id=186)
target Test01Form (id=109)
item01 StringBuilder (id=309)
item02 StringBuilder (id=310)

id=109のTest01Formが、本来のフォームクラスのインスタンスと思われます。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

基本的にバリデーションは対象のデータ型が決まっています。

大文字化などする場合はコンバートメソッドまたはアクセサメソッドで変更してください

投稿2017/12/03 23:13

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Ajax2017

2017/12/04 00:22

ご回答、ありがとうございました。 もっともな内容ではありますが、ひとつずつコーディングする必要があり、また、lombokを使っておりますので、setterのみ実装することとなり、メリットが半減してしまいますので、今回は見送らせていただきます。
guest

0

自己解決

諦めて、javascriptで、submitする前に変換することにしました。

投稿2017/12/11 10:25

Ajax2017

総合スコア7

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問