猿问

使用 Thymeleaf 和 Spring 从 <select> 标签正确发送对象

我有一个Spring Boot应用程序(一个库管理器),它使用Thymeleaf作为模板引擎。


该应用程序由两个主 s 和 组成。A 可以有一个 .@ComponentBookAuthorBookAuthor


我可以成功创建,检索,更新和删除任何,但无法正确创建或更新(尽管我可以检索和删除它们)。当发出插入的POST请求(插入已经存在的对象只是更新它)时,我在浏览器中收到错误,控制台会列出错误。AuthorBookBook400 Bad Request. Validation failed for object='book'.typeMismatch: Failed to convert property value of type 'java.lang.String' to required type 'com.springboot.demoweb.model.Author'


我正在检查发送到应用程序的请求,而不是发送包含根JSON“节点”内部属性的JSON“节点”(对不起,我不知道JSON是如何工作的),它只是发送了(我覆盖的结果。不重写该方法不会更改任何内容)。AuthorBookAuthor.toString()


下面是代码段:<select>


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

    ...


    <select th:field="*{author}">

        <option th:each="author : ${authors}"

                th:value="${author}"

                th:text="${author}"/>

    </select>


    ...

</form>

文件:Author.java


@Component

public class Author implements Serializable {

    private String id;

    private String name;


    @DateTimeFormat(pattern = "yyyy-MM-dd")

    private Calendar dateBorn;


    @DateTimeFormat(pattern = "yyyy-MM-dd")

    private Calendar dateDeath;


    ... // Getters and setters

}

文件:Book.java


@Component

public class Book {

    private String isbn;

    private String title;

    private Author author;


    ... // Getters and setters

}

和:BookController.java


@Controller

public class BookController {

    @GetMapping(value = "/books/edit", params = "isbn")

    public String viewEdit(@RequestParam("isbn") String isbn, Model model) {

        model.addAttribute("book", bookService.find(isbn));

        model.addAttribute("authors", authorService.all());

        return "books/edit";

    }


    // th:action="@{/books}" falls here

    @PostMapping("/books")

    public RedirectView create(Book book) {

        bookService.create(book);

        return new RedirectView("/books.html?isbn=" + book.getIsbn());

    }


    ... // Other mappings

}

变量和分别对 和 执行简单运算。bookServiceauthorServiceMap<String, Book>Map<String, Author>


我能为Thymeleaf将作为内部对象发送,而不仅仅是它的字符串表示形式做些什么?我是否必须在 HTML 页面中更改某些内容?控制器?添加百里香叶配置?AuthorBook


斯蒂芬大帝
浏览 157回答 1
1回答

守着一只汪

根据百里香酚文献,表单标记中 th:object 属性的值必须是变量表达式 (${...}),仅指定模型属性的名称,而不指定属性导航。这意味着像 ${seedStarter} 这样的表达式是有效的,但 ${seedStarter.data} 不是。您的 Thymeleaf 表单将呈现为所选作者的字符串值。无法在选项列表中绑定 Author 对象。因此,更改 Book 对象,添加新的属性 authorId(如果 Book 是 JPA 实体,请使用@Transient对此进行批注)。@Componentpublic class Book {&nbsp; &nbsp; &nbsp;private String isbn;&nbsp; &nbsp; &nbsp;private String title;&nbsp; &nbsp; &nbsp;private Author author;&nbsp; &nbsp; &nbsp;// New Transient attribute to bind authorId from select component&nbsp; &nbsp; &nbsp;private String authorId;}现在,可以使用 select 组件绑定此新属性,因为它符合上述文档。<form action="#" th:action="@{/books}" th:object="${book}" method="post">...<select th:field="*{authorId}">&nbsp; &nbsp; <option th:each="author : ${authors}"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; th:value="${author.id}"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; th:text="${author.name}"/></select>...在控制器中,可以使用 book.authorId 获取作者对象,并将其设置为 book 对象。@PostMapping("/books")public RedirectView create(Book book) {&nbsp; &nbsp; Author author = authorService.findById(book.authorId);&nbsp; &nbsp; book.setAuthor(author);&nbsp; &nbsp; bookService.create(book);&nbsp; &nbsp; return new RedirectView("/books.html?isbn=" + book.getIsbn());}
随时随地看视频慕课网APP

相关分类

Java
我要回答