私のプロジェクトには、フィールドの 1 つとして BigDecimal を含むクラスがあります。
@Entity
public class Product {
// ...
@DecimalMin("0.01")
private BigDecimal price;
// ...
}
thymeleaf には、このクラスのフィールドの入力を含むフォームがあり、価格を担当するフォームは次のとおりです。
<form ...>
<input type="number" step="any" th:field="*{price}">
</form>
このフォームから @ModelAttribute が返されると、製品の価格フィールドは null になります。価格が2倍だった頃も使えました。どうすればこれを機能させることができますか?回避策を考えました。この入力を @RequestParam として指定し、double 値を使用して Product.price を「手動で」初期化します。しかし、thymeleaf がそれを行うための解決策はありますか?
------------------------
これでうまくいくはずです。テストしたばかりですこれは、次のように Spring Boot 2.3.0 を使用して行います。
フォームにエンティティを直接使用すると、IMO のリポジビリティが乱雑になりすぎるため、フォーム データ オブジェクトを使用しています。
import javax.validation.constraints.DecimalMin;
import java.math.BigDecimal;
public class ProductFormData {
@DecimalMin("0.01")
private BigDecimal price;
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
}
次のようなコントローラを使用します:
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/product")
public class ProductController {
@GetMapping
public String product(Model model) {
model.addAttribute("product", new ProductFormData());
return "product";
}
@PostMapping
public String doSaveProduct(@ModelAttribute("product") ProductFormData formData) {
System.out.println("formData = " + formData.getPrice());
return "redirect:/product";
}
}
product.html テンプレートは次のようになります。
<!DOCTYPE html>
<html lang="en" xmlns:th="http:www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Product</title>
</head>
<body>
<h1>Product</h1>
<form th:action="@{/product}" th:object="${product}" method="post">
<input type="number" step="any" th:field="*{price}">
<button type="submit">submit</button>
</form>
</body>
</html>
フォームに数値を入力して「送信」を押すと、コンソールに値が表示されます。
4
DTO のようなものですか?フォームからデータを取得するだけのオブジェクトのようなものですか? (エンティティ オブジェクトの作成にはどちらが使用されますか?)パフォーマンスは?
– ジョニーブラボー
2020 年 9 月 5 日 16:29
1
確かに。次に、ProductFormData に toProduct() メソッドを持たせるか、ProductFormData をサービス メソッド (例: service.addProduct(ProductFormData)) に渡すか、ProductFormData を AddProductParameters に変換します (例: service.addProduct(formData.toProductParameters()))。これにより、エンティティにリッチなドメイン モデルを使用できるようになります。これがパフォーマンス上の問題となる状況は見たことがありません。
– ヴィム・デブラウウェ
2020 年 9 月 5 日 16:32
「エンティティのリーチ ドメイン モデル」により、たとえば、何らかの方法でエンティティ クラスを拡張したいという状況を指しますか?ところで、ご回答いただきありがとうございます。回答は本当に役に立ちますが、ProductFormData を使用するメリットが完全には理解できません。
– ジョニーブラボー
2020 年 9 月 5 日 16:49
1
つまり、ProductFormData は通常、String、int、BigDecimal を使用します。エンティティ内のどこで、Price クラスまたは Quantity クラスを使用することもできます。おそらく、Product にはサプライヤー参照がありますが、ProductFormData では、Thymeleaf フォームにバインドしやすいため、文字列のsupplierId を使用します。
– ヴィム・デブラウウェ
2020 年 9 月 5 日 16:52