在暑假期间,我试图通过开发一个简单的Web应用程序来学习Spring和其他相关技术,但是Thymeleaf阻碍了我的进步。
该程序基于两个实体类:
Invoice.java:
@Entity
public class Invoice {
@Id
private String invoiceId;
@NotNull
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate issueDate;
//getters and setters
}
TrasportOrder.java:
@Entity
public class TransportOrder {
@Id
private int number;
@NotNull
private BigDecimal value;
@ManyToOne
private Invoice invoice;
//getters and setters
}
我正在使用InvoiceController中的方法获取用于添加发票的表单:
@GetMapping(path = "/add")
public String getForm(Model model) {
model.addAttribute("unusedOrders", service.getInvoiceOrders(null));
model.addAttribute("orders", new ArrayList<TransportOrder>());
model.addAttribute("invoice", new Invoice());
return "addInvoice";
}
unusedOrders 是用户可以选择的订单列表, orders 是一个包含用户选择的订单的列表 发票只是以表单形式创建的发票。
我的表单包含有关发票的文本和数据输入,然后对订单进行多次选择:
<!-- I used to define th:object here and used th:field in the inputs, however changed it to use th:value everywhere -->
<form action="/invoices/add" method="post">
<table>
<tr>
<th>
Invoice ID:
</th>
<th>
<input type="text" th:value="${invoice.invoiceId}" name="invoiceId"/>
</th>
</tr>
<tr>
<!-- a few other inputs -->
</tr>
<tr>
<th>
Orders:
</th>
<th>
<!-- problem may lie here -->
<select id="orders" th:value="${orders}" multiple="multiple">
<option th:each="unusedOrder: ${unusedOrders}"
th:value="${unusedOrder.number}"
th:text="${unusedOrder}">Unused orders to choose from</option>
</select>
</th>
</tr>
</table>
<button type="submit">Next</button>
</form>
我已经阅读了Thymeleaf的文档和论坛以及一些SO问题,但是它们仍然使我对th:object
,th:field
,th:value
和其他表单如何工作感到困惑,尤其是带有多个select
标签。
提交后,表单将POST请求发送到同一控制器中的方法:
@PostMapping(path = "/add")
public String addInvoice(@ModelAttribute Invoice invoice,
BindingResult result,
@ModelAttribute("orders") ArrayList<TransportOrder> orders,
Model model) {
//invoice and orders saving logic, etc.
return "viewInvoices";
}
我的问题是从数据库中正确检索了invoice
并将其保留在数据库中,但是orders
列表仍然为空。 我希望它会填充有表单中选择的订单。我不知道,是否是因为@ModelAttribute
注释(我也尝试了@RequestAttribute
却没有成功),Thymeleaf标签或其他任何内容。
答案 0 :(得分:0)
好的,所以我决定再次为答案而战,幸运的是我偶然发现了答案。
基于this tutorial,我创建了一个包装类ChosenOrdersDTO
:
public class ChosenOrdersDTO {
private List<TransportOrder> chosenOrders;
//constructor, getters, setters...
}
我将其添加到第一个模型中(如下更改了getForm()
方法):
model.addAttribute("chosenOrders", new ChosenOrdersDTO(new ArrayList<>()));
我使用th:field
标记的形式,类似于以前的字段:
<select id="orders" th:field="${chosenOrders.chosenOrders}" multiple="multiple">
在第二个控制器中,我能够将ChosenOrdersDTO
类中包装的列表作为@ModelAttribute
:
@PostMapping(path = "/add")
public String addInvoice(@ModelAttribute Invoice invoice,
BindingResult
@ModelAttribute ChosenOrdersDTO chosenOrders,
Model model)