首页 > 解决方案 > 正确发送对象用 Thymeleaf 和 Spring 标记我有一个使用 Thymeleaf 作为模板引擎的 Spring Boot 应用程序(库管理器)。该应用程序由两个主要的@Components 组成,Book 和 Author。一本书可以有一个作者。我可以成功创建、检索、更新和删除任何作者,但无法正确创建或更新书籍(尽管我可以检索和删除它们)。当发出 POST 请求以插入 Book 时(插入已经存在的对象只会更新它),我收到 400 Bad Request。对象='book' 的验证

问题描述

标签: javaspringspring-bootthymeleaf

解决方案


根据百里香文档

表单标记中 th:object 属性的值必须是变量表达式 (${...}),仅指定模型属性的名称,而无需属性导航。这意味着像 ${seedStarter} 这样的表达式是有效的,但 ${seedStarter.data} 不是。

您的 Thymeleaf 表单呈现所选作者的 toString 值。无法在选项列表中绑定作者对象。因此,更改 Book 对象添加一个新属性authorId(如果 Book 是 JPA 实体,请使用 @Transient 对其进行注释)。

@Component
public class Book {
     private String isbn;
     private String title;
     private Author author;
     // New Transient attribute to bind authorId from select component
     private String authorId;
}

现在,可以使用 select 组件绑定这个新属性,因为它符合上述文档。

<form action="#" th:action="@{/books}" th:object="${book}" method="post">
...

<select th:field="*{authorId}">
    <option th:each="author : ${authors}"
            th:value="${author.id}"
            th:text="${author.name}"/>
</select>

...

在您的控制器中,您可以使用 book.authorId 获取作者对象并将其设置为 book 对象。

@PostMapping("/books")
public RedirectView create(Book book) {
    Author author = authorService.findById(book.authorId);
    book.setAuthor(author);
    bookService.create(book);
    return new RedirectView("/books.html?isbn=" + book.getIsbn());
}

推荐阅读