Spring MVC 和 Thymeleaf:将带有列表实例变量的对象传递给控制器

Spring MVC & Thymeleaf: pass object with list instance variable to controller

我有以下域对象:

public class Pizza extends AbstractProduct {
    public enum Size { SMALL, MEDIUM, LARGE }

    private Size size;
    private List<Ingredient> ingredients;

    // Getters and setters
}

此对象包含成分对象列表:

public class Ingredient {
    public enum Type { SAUCE, VEGGIES, PROTEIN, CHEESE }

    private int id;
    private String name;
    private Type type;

    // Getters and setters
}

我想在 2 个控制器之间传递 Pizza 对象。

首先,我从披萨服务中检索披萨对象并将其传递给视图。

@Controller
@RequestMapping("/pizzas")
public class PizzaController {
   
    @GetMapping("/{id}")
    public String getPizzaInfo(@PathVariable int id, Model model) {
        Pizza pizza = // Getting pizza
        model.addAttribute("pizza", pizza);
        return "pizza/pizza-info";
    }
}

然后,用户点击“添加到购物车”按钮,发送 POST 请求,我在 CartController 中收到此请求。

@Controller
@RequestMapping("/cart")
public class CartController {

    @PostMapping("/add-pizza")
    public String addPizzaToOrder(@ModelAttribute Pizza pizza) {
        // Order business logic
   }
}

我使用 html 隐藏输入从传入 PizzaController 的 Pizza 对象获取数据。

    <form method="post" th:object="${pizza}" th:action="@{/cart/add-pizza}">
        <input type="hidden" th:field="${pizza.id}" id="id">
        <input type="hidden" th:field="${pizza.name}" id="name">
        <input type="hidden" th:field="${pizza.price}" id="price">
        <input type="hidden" th:field="${pizza.imageUrl}" id="img_url">

        <label>
            <select name="size">
            <option th:each="size : ${T(pizzaonline.service.domain.Pizza.Size).values()}"
                th:value="${size}" th:text="${size}"></option>
            </select>
        </label>

        <button>Add to cart</button>
</form>

除了一个字段 - 成分外,一切正常。我需要语义上等于 <input type="hidden" th:field="${pizza.ingredients}" id="ingredients"> 的内容来复制配料表。 我该怎么做?

如果你想像做披萨一样做,它看起来像这样:

<th:block th:each="ingredient, status: ${pizza.ingredients}">
  <input type="hidden" th:field="*{ingredients[__${status.index}__].id}" />
  <input type="hidden" th:field="*{ingredients[__${status.index}__].name}" />
  <input type="hidden" th:field="*{ingredients[__${status.index}__].type}" />
</th:block>

您还可以查看在控制器上使用 @SessionAttributes 属性,并简单地省略所有隐藏字段。它会将指定的模型属性临时存储在会话中,并保留已经指定的字段的值。