Spring MVC と Thymeleaf 2.x と Value Object
Spring Boot 1.2.4を前提にしています。
Value Object をどうにかして不変にしたいなと思いがんばる話です。
がんばりたくない人はお帰り下さい。
Value Objectへのデータバインド
Spring MVCではStringのコンストラクタ1つだけを持つオブジェクトにリクエストパラメータを自動バインドしてくれる。 これを利用してフォームの値をオブジェクトにバインドしようとするものの…
//Value Object 普段はBeanValidationとか付けるけど省略 public class Price { private final BigDecimal value; public Price(String value) { this.value = BigDecimal.valueOf(value); } public String getValue() {...} } //Formにバインドする商品登録オブジェクト。商品名とかは省略 public class ItemRegisterRequest { Price price; public Price getPrice() {...} public void setPrice(Price price) {...} } //Controllerは省略…
バインドするForm
<form th:object="${parchase}"> <input type="text" th:field="*{price}"/> </form>
これだとパラメータのバインドは上手く行くものの *{price}がPriceオブジェクトのtoString結果を出力してしまう。 なので、
<form th:object="${parchase}"> <input type="text" name="price" th:value="*{price.value}"/> </form>
として、nameと、valueを分けるはめになる。
微妙かと思ったけどこれはこれでもしかしたらわかりやすいのではと…(思いたい
あと、データソース層にMyBatisを使ってると、結局Value Objectのメンバ変数のfinalを外す ことになって…コンパイラがチェックしてくれるレベルの不変性は失われてしまう。(また別に書く
論理的に不変ならまぁ及第点か