我是Thymeleaf的新手,我尝试使用Thymeleaf和Spring执行简单的表单提交。控制器看起来像这样
@Slf4j
@Controller
public class BookController {
private static final String BOOK_BOOKFORM_URL = "book/bookform";
private BookService bookService;
@Autowired
public BookController(BookService bookService) {
this.bookService = bookService;
}
@GetMapping("/book/{id}/show")
public String showBookById(@PathVariable String id, Model model) {
model.addAttribute("book", bookService.findById(Long.valueOf(id)));
return "book/bookshow";
}
@GetMapping("book/new")
public String newBook(Model model) {
model.addAttribute("book", new BookCommand());
return "book/bookform";
}
@GetMapping("book/{id}/update")
public String updateBook(@PathVariable String id, Model model) {
model.addAttribute("book",
bookService.findCommandById(Long.valueOf(id)));
return BOOK_BOOKFORM_URL;
}
@PostMapping("book/")
public String saveOrUpdate(@Valid @ModelAttribute("book") BookCommand
command,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
bindingResult.getAllErrors().forEach(objectError -> {
log.debug(objectError.toString());
});
return BOOK_BOOKFORM_URL;
}
BookCommand savedCommand = bookService.saveBookCommand(command);
return "redirect:/book/" + savedCommand.getId() + "/show";
}
@GetMapping("book/{id}/delete")
public String deleteById(@PathVariable String id) {
log.debug("Deleting id: " + id);
bookService.deleteById(Long.valueOf(id));
return "redirect:/";
}
}
Thymeleaf的形式如下
<body>
<!--/*@thymesVar id="book" type="com.sombra.test.firsttry.model.Book"*/-->
<div class="container-fluid" style="margin-top: 20px">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form class="form" th:modelAttribute="book" th:object="${book}"
th:action="@{/book/}" method="post">
<input type="hidden" th:field="*{id}"/>
<div class="pannel-group">
<div class="panel panel-primary">
<div class="panel-heading">
<h1 class="panel-title">Змінити інформацію про книгу</h1>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-3 form-group">
<label>Ім'я:</label>
<input type="text" class="form-control" th:field="*{name}"/>
</div>
<div class="col-md-3 form-group">
<label>Опубліковано:</label>
<input type="text" class="form-control" th:field="*
{published}"/>
</div>
<div class="col-md-3 form-group">
<label>Жанр:</label>
<input type="text" class="form-control" th:field="*{genre}"/>
</div>
<div class="col-md-3 form-group">
<label>Рейтинг:</label>
<input type="text" class="form-control" th:field="*{rating}"/>
</div>
</div>
<button type="submit" class="btn btn-primary">Save</button>
</div>
</div>
</div>
</form>
</div>
Book和BookCommand是使用Spring的Converter相互转换的POJO。 当我按下提交按钮时,控制器方法saveOrUpdate既不会将我重定向到包含该书信息的页面,而在成功保存的情况下它必须这样做,也不会记录来自BindingResult的错误消息。那么,这可能是什么原因?
答案 0 :(得分:1)
将此@PostMapping("book/")
更改为@PostMapping("/book/")
如果上述方法不起作用,请通过删除斜线与下面的方法一起使用。
th:action="@{/book/}"
,因为问题仅在于URL匹配。
答案 1 :(得分:0)
使用@SessionAttributes批注 像这样
@Slf4j
@Controller
@SessionAttributes("book")
public class BookController {
private static final String BOOK_BOOKFORM_URL = "book/bookform";
private BookService bookService;
@Autowired
public BookController(BookService bookService) {
this.bookService = bookService;
}
@GetMapping("/book/{id}/show")
public String showBookById(@PathVariable String id, Model model) {
model.addAttribute("book", bookService.findById(Long.valueOf(id)));
return "book/bookshow";
}
@GetMapping("book/new")
public String newBook(Model model) {
model.addAttribute("book", new BookCommand());
return "book/bookform";
}
@GetMapping("book/{id}/update")
public String updateBook(@PathVariable String id, Model model) {
model.addAttribute("book",
bookService.findCommandById(Long.valueOf(id)));
return BOOK_BOOKFORM_URL;
}
@PostMapping("book/")
public String saveOrUpdate(@Valid @ModelAttribute("book") BookCommand
command,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
bindingResult.getAllErrors().forEach(objectError -> {
log.debug(objectError.toString());
});
return BOOK_BOOKFORM_URL;
}
BookCommand savedCommand = bookService.saveBookCommand(command);
return "redirect:/book/" + savedCommand.getId() + "/show";
}
@GetMapping("book/{id}/delete")
public String deleteById(@PathVariable String id) {
log.debug("Deleting id: " + id);
bookService.deleteById(Long.valueOf(id));
return "redirect:/";
}
}
答案 2 :(得分:0)
感谢大家的假设和帮助! 最后,我找到了问题的原因。问题是关于存储表单的字段发布日期。 Spring无法将插入的字符串转换为Date,但是由于某些原因,使用BindingResult错误日志记录时没有错误记录在块中。解决方案是像这样向控制器添加Date的活页夹:
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Date.class, new CustomDateEditor(new
SimpleDateFormat("yyyy-MM-dd"), true));
}