如何在Spring MVC中将用户输入与BigDecimal对象字段绑定?

huangapple go评论78阅读模式
英文:

How to bind user input with a BigDecimal object field in Spring MVC?

问题

在我的项目中我有一个类其中一个字段是 `BigDecimal` 类型
```java
@Entity
public class Product {

    // ...
   
    @DecimalMin("0.01")
    private BigDecimal price;

    // ...
}

thymeleaf 中,我有一个表单,用于输入该类的字段,负责 price 的部分是:

<form ...>
   <input type="number" step="any" th:field="*{price}">
</form>

当从该表单返回 @ModelAttribute 时,productprice 字段为 null。当 pricedouble 类型时,它是有效的。我该如何使其工作?我想到了一个解决方法 - 将此输入作为 @RequestParam,然后使用 double 值手动初始化 Product.price,但是否有某种解决方案让 thymeleaf 为我执行这些操作?


<details>
<summary>英文:</summary>

In my project I have a class with `BigDecimal` as one of its fields. 
```java
@Entity
public class Product {

    // ...
   
    @DecimalMin(&quot;0.01&quot;)
    private BigDecimal price;

    // ...
}

In thymeleaf I have a form with inputs for fields of this class and the one responsible for price is:

&lt;form ...&gt;
   &lt;input type=&quot;number&quot; step=&quot;any&quot; th:field=&quot;*{price}&quot;&gt;
&lt;/form&gt;

When the @ModelAttribute is returned from this form, the price field of product is null. It used to work when the price was a double. How can I make this work? I thought of a workaround - to have this input as a @RequestParam and then initialize the Product.price using the double value 'manually' but is there some solution so that thymeleaf does that for me?

答案1

得分: 2

以下是您要翻译的内容:

这应该可以工作。我刚刚使用Spring Boot 2.3.0进行了如下测试:

我正在使用一个表单数据对象,因为直接在表单中使用实体会使责任过多:

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>

当我在表单中输入一个数字并点击“提交”时,我可以在控制台中看到打印出的值。

英文:

That should work. I just tested this using Spring Boot 2.3.0 as follows:

I am using a form data object, as directly using your entity for a form clutters reposibilities too much IMO:

import javax.validation.constraints.DecimalMin;
import java.math.BigDecimal;

public class ProductFormData {

    @DecimalMin(&quot;0.01&quot;)
    private BigDecimal price;

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }
}

With a controller like this:

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(&quot;/product&quot;)
public class ProductController {

    @GetMapping
    public String product(Model model) {
        model.addAttribute(&quot;product&quot;, new ProductFormData());
        return &quot;product&quot;;
    }

    @PostMapping
    public String doSaveProduct(@ModelAttribute(&quot;product&quot;) ProductFormData formData) {
        System.out.println(&quot;formData = &quot; + formData.getPrice());

        return &quot;redirect:/product&quot;;
    }
}

And the product.html template like this:

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot; xmlns:th=&quot;http:www.thymeleaf.org&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;title&gt;Product&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;Product&lt;/h1&gt;
&lt;form th:action=&quot;@{/product}&quot; th:object=&quot;${product}&quot; method=&quot;post&quot;&gt;
    &lt;input type=&quot;number&quot; step=&quot;any&quot; th:field=&quot;*{price}&quot;&gt;
    &lt;button type=&quot;submit&quot;&gt;submit&lt;/button&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;

When I type a number in the form and press 'submit', I see the value printed in the console.

huangapple
  • 本文由 发表于 2020年9月5日 05:28:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/63748223.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定