Spring - Thymeleaf:异常处理模板
Posted
技术标签:
【中文标题】Spring - Thymeleaf:异常处理模板【英文标题】:Spring - Thymeleaf: Exception processing template 【发布时间】:2019-10-11 21:10:57 【问题描述】:我正在关注 Spring in Action 第 5 版一书,但我认为这是一个错误。
这是本书的 GitHub。我已经到达第 3 章 tacos-jdbc source of code
提交订单时突然出现错误:
并以这种方式在终端上:
2019-05-25 16:58:18.164 错误 11777 --- [nio-8080-exec-7] org.thymeleaf.TemplateEngine : [THYMELEAF][http-nio-8080-exec-7] 异常处理模板 “orderForm”:模板解析时出错(模板: "类路径资源 [templates/orderForm.html]")
org.thymeleaf.exceptions.TemplateInputException:发生错误 在模板解析期间(模板:“类路径资源 [模板/orderForm.html]")
订单控制器:
@Controller
@RequestMapping("/orders")
@SessionAttributes("order")
public class OrderController
private OrderRepository orderRepo;
public OrderController(OrderRepository orderRepo)
this.orderRepo = orderRepo;
@GetMapping("/current")
public String orderForm()
return "orderForm";
@PostMapping
public String processOrder(@Valid Order order, Errors errors,
SessionStatus sessionStatus)
if (errors.hasErrors())
return "orderForm";
orderRepo.save(order);
sessionStatus.setComplete();
return "redirect:/";
和orderForm:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Taco Cloud</title>
<link rel="stylesheet" th:href="@/styles.css" />
</head>
<body>
<form method="POST" th:action="@/orders" th:object="$order">
<h1>Order your taco creations!</h1>
<img th:src="@/images/TacoCloud.png"/>
<a th:href="@/design" id="another">Design another taco</a><br/>
<div th:if="$#fields.hasErrors()">
<span class="validationError">
Please correct the problems below and resubmit.
</span>
</div>
<h3>Deliver my taco masterpieces to...</h3>
<label for="name">Name: </label>
<input type="text" th:field="*name"/>
<br/>
<label for="street">Street address: </label>
<input type="text" th:field="*street"/>
<br/>
<label for="city">City: </label>
<input type="text" th:field="*city"/>
<br/>
<label for="state">State: </label>
<input type="text" th:field="*state"/>
<br/>
<label for="zip">Zip code: </label>
<input type="text" th:field="*zip"/>
<br/>
<label for="ccNumber">Credit Card #: </label>
<input type="text" th:field="*ccNumber"/>
<span class="validationError"
th:if="$#fields.hasErrors('ccNumber')"
th:errors="*ccNumber">CC Num Error</span>
<label for="ccExpiration">Expiration: </label>
<input type="text" th:field="*ccExpiration"/>
<br/>
<label for="ccCVV">CVV: </label>
<input type="text" th:field="*ccCVV"/>
<br/>
<input type="submit" value="Submit order"/>
</form>
</body>
</html>
【问题讨论】:
【参考方案1】:我认为您应该处理 orderForm.html 中所有输入中验证错误的显示,如下所示:(Source Git)
<!-- tag::allButValidation[] -->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Taco Cloud</title>
<link rel="stylesheet" th:href="@/styles.css" />
</head>
<body>
<form method="POST" th:action="@/orders" th:object="$order">
<h1>Order your taco creations!</h1>
<img th:src="@/images/TacoCloud.png"/>
<a th:href="@/design" id="another">Design another taco</a><br/>
<div th:if="$#fields.hasErrors()">
<span class="validationError">
Please correct the problems below and resubmit.
</span>
</div>
<h3>Deliver my taco masterpieces to...</h3>
<label for="name">Name: </label>
<input type="text" th:field="*name"/>
<!-- end::allButValidation[] -->
<span class="validationError"
th:if="$#fields.hasErrors('name')"
th:errors="*name">Name Error</span>
<!-- tag::allButValidation[] -->
<br/>
<label for="street">Street address: </label>
<input type="text" th:field="*street"/>
<!-- end::allButValidation[] -->
<span class="validationError"
th:if="$#fields.hasErrors('street')"
th:errors="*street">Street Error</span>
<!-- tag::allButValidation[] -->
<br/>
<label for="city">City: </label>
<input type="text" th:field="*city"/>
<!-- end::allButValidation[] -->
<span class="validationError"
th:if="$#fields.hasErrors('city')"
th:errors="*city">City Error</span>
<!-- tag::allButValidation[] -->
<br/>
<label for="state">State: </label>
<input type="text" th:field="*state"/>
<!-- end::allButValidation[] -->
<span class="validationError"
th:if="$#fields.hasErrors('state')"
th:errors="*state">State Error</span>
<!-- tag::allButValidation[] -->
<br/>
<label for="zip">Zip code: </label>
<input type="text" th:field="*zip"/>
<!-- end::allButValidation[] -->
<span class="validationError"
th:if="$#fields.hasErrors('zip')"
th:errors="*zip">Zip Error</span>
<!-- tag::allButValidation[] -->
<br/>
<h3>Here's how I'll pay...</h3>
<!-- tag::validatedField[] -->
<label for="ccNumber">Credit Card #: </label>
<input type="text" th:field="*ccNumber"/>
<!-- end::allButValidation[] -->
<span class="validationError"
th:if="$#fields.hasErrors('ccNumber')"
th:errors="*ccNumber">CC Num Error</span>
<!-- tag::allButValidation[] -->
<!-- end::validatedField[] -->
<br/>
<label for="ccExpiration">Expiration: </label>
<input type="text" th:field="*ccExpiration"/>
<!-- end::allButValidation[] -->
<span class="validationError"
th:if="$#fields.hasErrors('ccExpiration')"
th:errors="*ccExpiration">CC Num Error</span>
<!-- tag::allButValidation[] -->
<br/>
<label for="ccCVV">CVV: </label>
<input type="text" th:field="*ccCVV"/>
<!-- end::allButValidation[] -->
<span class="validationError"
th:if="$#fields.hasErrors('ccCVV')"
th:errors="*ccCVV">CC Num Error</span>
<!-- tag::allButValidation[] -->
<br/>
<input type="submit" value="Submit order"/>
</form>
</body>
</html>
<!-- end::allButValidation[] -->
我认为您没有按照本章中解释的 bean 中添加的验证规则在表单中插入正确的信息。通过显示验证错误,您将在提交订单时准确知道哪个输入没有正确插入。
在调查您的代码之后。 Order.java 中的属性名称与视图页面 orderForm.html 中的属性名称不同
例如,在 orderForm 中,属性是 name
<h3>Deliver my taco masterpieces to...</h3>
<label for="name">Name: </label>
<input type="text" th:field="*name"/>
而在 Order.java 中是 deliveryName。
@NotBlank(message="Delivery name is required")
private String deliveryName;
解决方法是在Order.java和orderForm.html页面中使用同名的属性。
【讨论】:
我遇到了同样的错误。我到达一个页面,我需要单击复选框并为我的 taco 命名。提交订单后,我在后续页面中收到错误消息。问题与验证无关。 2019-05-28 21:01:27.110 错误 5417 --- [nio-8080-exec-8] org.thymeleaf.TemplateEngine:[THYMELEAF][http-nio-8080-exec-8] 异常处理模板“orderForm” : 模板解析时出错 (template: "class path resource [templates/orderForm.html]") org.thymeleaf.exceptions.TemplateInputException: An error occurred during. 这很奇怪。您是否更新了 orderForm.html、填写输入并获取解析错误消息?你能添加你的 Order 和 Taco 类吗?或者你有 Git 中你的代码的源代码吗?我使用相同的 oderForm.html 运行应用程序并且没有错误。 今晚我会点它,现在我在工作。谢谢您的帮助。如果您愿意,我可以通过电子邮件将项目发送给您【参考方案2】:我修复了此代码添加 delivery
前缀:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Taco Cloud</title>
<link rel="stylesheet" th:href="@/styles.css" />
</head>
<body>
<form method="POST" th:action="@/orders" th:object="$order">
<h1>Order your taco creations!</h1>
<img th:src="@/images/TacoCloud.png"/>
<h3>Your tacos in this order:</h3>
<a th:href="@/design" id="another">Design another taco</a><br/>
<ul>
<li th:each="taco : $order.tacos"><span th:text="$taco.name">taco name</span></li>
</ul>
<div th:if="$#fields.hasErrors()">
<span class="validationError">
Please correct the problems below and resubmit.
</span>
</div>
<h3>Deliver my taco masterpieces to...</h3>
<label for="deliveryName">Name: </label>
<input type="text" th:field="*deliveryName"/>
<span class="validationError"
th:if="$#fields.hasErrors('deliveryName')"
th:errors="*deliveryName">Name Error</span>
<br/>
<label for="deliveryStreet">Street address: </label>
<input type="text" th:field="*deliveryStreet"/>
<span class="validationError"
th:if="$#fields.hasErrors('deliveryStreet')"
th:errors="*deliveryStreet">Street Error</span>
<br/>
<label for="deliveryCity">City: </label>
<input type="text" th:field="*deliveryCity"/>
<span class="validationError"
th:if="$#fields.hasErrors('deliveryCity')"
th:errors="*deliveryCity">City Error</span>
<br/>
<label for="deliveryState">State: </label>
<input type="text" th:field="*deliveryState"/>
<span class="validationError"
th:if="$#fields.hasErrors('deliveryState')"
th:errors="*deliveryState">State Error</span>
<br/>
<label for="deliveryZip">Zip code: </label>
<input type="text" th:field="*deliveryZip"/>
<span class="validationError"
th:if="$#fields.hasErrors('deliveryZip')"
th:errors="*deliveryZip">Zip Error</span>
<br/>
<h3>Here's how I'll pay...</h3>
<label for="ccNumber">Credit Card #: </label>
<input type="text" th:field="*ccNumber"/>
<span class="validationError"
th:if="$#fields.hasErrors('ccNumber')"
th:errors="*ccNumber">CC Num Error</span>
<br/>
<label for="ccExpiration">Expiration: </label>
<input type="text" th:field="*ccExpiration"/>
<span class="validationError"
th:if="$#fields.hasErrors('ccExpiration')"
th:errors="*ccExpiration">CC Num Error</span>
<br/>
<label for="ccCVV">CVV: </label>
<input type="text" th:field="*ccCVV"/>
<span class="validationError"
th:if="$#fields.hasErrors('ccCVV')"
th:errors="*ccCVV">CC Num Error</span>
<br/>
<input type="submit" value="Submit order"/>
</form>
</body>
</html>
【讨论】:
【参考方案3】:您在 orderForm
模板中使用了 th:object="$order"
,但 Thymeleaf 不知道。
你必须让 Thymeleaf 知道这个对象,方法是像这样将它传递给模板
@GetMapping("/current")
public ModelAndView orderForm()
ModelAndView mv = new ModelAndView("orderForm");
mv.addObject("order", new Order());
return mv;
注意:您必须在模板中使用该对象的所有位置从控制器层传递该对象。
更新 1
同时更新你的发布方法
@PostMapping
public ModelAndView processOrder(@Valid Order order, Errors errors,
SessionStatus sessionStatus)
if (errors.hasErrors())
ModelAndView mv = new ModelAndView("orderForm");
mv.addObject("order", new Order());
return mv;
orderRepo.save(order);
sessionStatus.setComplete();
return new ModelAndView("redirect:/");
【讨论】:
同样的错误。如果我需要展示更多课程,请告诉我 当您提交订单时,您必须在该方法的第三行添加该对象。因为您还展示了需要order
对象的orderForm
模板。
你能告诉我怎么做吗?正如你所说,在你的第一次演讲中,我改变了。
第一个返回的是ModelAndView,第二个是String
是的,再检查一遍【参考方案4】:
我认为你可以这样做
@Controller
public class OrderController
@GetMapping("/orders")
public String orders(Order order)
return "orderForm";
@PostMapping("/orders")
public String orderForm(@Valid Order order, BindingResult result, Model model)
if(result.hasErrors())
return "orderForm";
else
retrun "your_success_view";
【讨论】:
我也试过你的方法,终端没有报错,但是提交后有一个空白页,就像我发布的第一张图片一样,直到状态500 也许@Valid @ModelAttribute("order") Order order
在后期映射中?以上是关于Spring - Thymeleaf:异常处理模板的主要内容,如果未能解决你的问题,请参考以下文章
评估 SpringEL 表达式的 Spring Boot 异常
Spring Boot 2.4.2 和 Thymeleaf 3.0.12 - 访问静态方法
在基于 Web 的 Spring 范围中使用 Thymeleaf 处理 HTML 文件并将处理后的模板存储为字符串
Spring Boot使用thymeleaf模板时报异常:template might not exist or might not be accessible by any of the confi