我收到错误:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'description' available as request attribute.
你能帮我纠正这个错误吗?
这是我尝试将 Review 模型中的字段添加到 Thymeleaf reviewBook.html 表单的代码。我不确定如何将评论模型中的描述和评论字段添加到 Thymeleaf 表单中。 我试图创建一个表单供用户撰写评论,但一本书可以有很多评论,所以我认为我需要使用 Book 实体作为表单的基础。 这是正确的吗?
BookController.java
@Controller
public class BookController {
public BookController() {
}
@Autowired
private AppUserRepository appUserRepository;
@Autowired
private BookRepository bookRepository;
@Autowired
private ReviewRepository reviewRepository;
@Autowired
private RatingRepository ratingRepository;
@GetMapping("/reviewBook")
public String showReviewForm(Model model) {
Book book = new Book();
Review review = new Review();
List<Rating> ratings = ratingRepository.findAll();
model.addAttribute("book", new Book());
model.addAttribute("review", new Review());
model.addAttribute("allRatings", ratings);
return "reviewBook";
}
reviewBook.html
<div class=" container py-5" >
<div class="row">
<div class="col-lg-6 rounded border p-3" >
<h2 class="text-center mb-3">Create Review</h2>
<hr />
<div th:if="${success}" class="alert alert-success alert-
dismissable fade show" role="alert">
<strong>Review Created Successfully!</strong>
</div>
<form method="post" th:object="${book}">
<input type="hidden" th:name="${_csrf.parameterName}"
th:value="${_csrf.token}" />
<div class="row mb-3">
<label class="col-sm-4 col-form-label"
th:for="title">Title*</label>
<div class="col-sm-8 ">
<input class="form-control" type="text"
id="title" name="title" th:field="${book.title}">
<p th:if="${#fields.hasErrors('title')}"
th:errorclass="text-danger"
th:errors="${book.title}"></p>
</div>
</div>
<div class="row mb-3">
<label class="col-sm-4 col-form-label"
th:for="aFirstName">Author's First Name*</label>
<div class="col-sm-8 ">
<input class="form-control" type="text"
id="aFirstName" name="aFirstName" th:field="${book.aFirstName}" >
<p th:if="${#fields.hasErrors('aFirstName')}"
th:errorclass="text-danger"
th:errors="${book.aFirstName}"></p>
</div>
</div>
<div class="row mb-3">
<label class="col-sm-4 col-form-label"
th:for="aLastName">Author's Last Name*</label>
<div class="col-sm-8 ">
<input class="form-control" type="text"
id="aLastName" name="aLastName" th:field="${book.aLastName}" >
<p th:if="${#fields.hasErrors('aLastName')}"
th:errorclass="text-danger"
th:errors="${book.aLastName}"></p>
</div>
</div>
<div class="row mb-3">
<label class="col-sm-4 col-form-label"
th:for="description">Brief Description*</label>
<div class="col-sm-8 ">
<textarea class="form-control" type="text"
placeholder="Enter review..," id="description"
name="description" th:field="*{description}"></textarea>
<p th:if="${#fields.hasErrors('description')}"
th:errorclass="text-danger"
th:errors="*{description}"></p>
</div>
</div>
<div class="row mb-3">
<label class="col-sm-4 col-form-label"
th:for="review">Review*</label>
<div class="col-sm-8 ">
<input class="form-control" type="text"
id="review" name="review" th:field="*{review}" >
<p th:if="${#fields.hasErrors('review')}"
th:errorclass="text-danger"
th:errors="*{review}"></p>
</div>
</div>
<div class="row mb-3">
<label class="col-sm-4 col-form-label"
th:for="rating">Rating*</label>
<div class="col-sm-8 ">
<select th:field="*{ratings}" multiple="multiple">
<option th:each="rating: ${allRatings}"
th:value=${rating.ratingId}
th:text=${rating.rating}>
</option>
</select>
</div>
</div>
<div class="row mb-3">
<div class="offset-sm-4 col-sm-4 d-grid">
<button type="submit" class="btn btn-
primary">Submit</button>
</div>
<div class="col-sm-4 d-grid">
<a href="/" class="btn btn-outline-
primary">Cancel</a>
</div>
</div>
</form>
</div>
</div>
</div>
</body>
Book.java
@Entity
@Table(name="books")
public class Book {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private int id;
@NotEmpty
private String title;
private String aFirstName;
private String aLastName;
@OneToMany(mappedBy = "book", cascade = CascadeType.ALL)
private List<Review> review;
评论.html
@Entity
@Table(name="reviews")
public class Review {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@NotEmpty
private String description;
@NotEmpty
private String review;
private Date revDate;
@ManyToOne
@JoinColumn(name= "appUser_id")
private AppUser appUser;
@ManyToOne
@JoinColumn(name="book_id")
private Book book;
@ManyToOne
@JoinColumn(name="rating_id")
private Rating rating;
您对我如何纠正此错误有什么建议吗?我的错误是在控制器、表单还是模型关系方面?
由于您使用一本书作为对象 -
th:object="${book}"
- 表达式 th:field="*{description}"
表示 ${book.description} 不存在并导致您的错误。
如果您正在编辑单个
review
,则应使用review
作为您的th:object
,然后*{description}
才是正确的。
如果您想编辑书籍以及书籍对象上的多个评论,则可以使用
book
作为 th:object
,编辑书籍的表单将如下所示:
<form method="post" th:object="${book}">
<!-- book fields -->
<input type="text" th:field="*{title}">
<!-- reviews -->
<div th:each="review, stat: ${book.review}">
<input type="text" th:field="*{review[__${stat.index}__].description}">
<input type="text" th:field="*{review[__${stat.index}__].review}">
</div>
</form>
您必须审查已经存在的对象。 本教程更深入地介绍它。