У меня есть приложение Spring Boot (менеджер библиотеки), которое использует Thymeleaf в качестве механизма шаблонов.
Приложение состоит из двух основных @Component
s, Book
и Author
.Book
может иметь один Author
.
. Я могу успешно создавать, извлекать, обновлять и удалять любые Author
, но не могу правильно создавать или обновлять Book
(хотя я могу получитьи удалить их).При выполнении запроса POST для вставки Book
(вставка уже существующего объекта просто обновляет его), в браузере появляется ошибка 400 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), содержащего свойства Author
внутри корневого «узла» JSON Book
, онпросто отправил результаты Author.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
file:
@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
}
Переменные bookService
и authorService
выполнять простые операции с Map<String, Book>
и Map<String, Author>
соответственно.
Что я могу сделать для того, чтобы Thymeleaf отправлял Author
как объект внутри Book
, а не только его строковое представление?Нужно ли что-то менять на странице HTML?Контроллер?Добавить конфигурацию Thymeleaf?