Spring - Thymeleaf: шаблон обработки исключений - PullRequest
2 голосов
/ 25 мая 2019

Я следую книге «Весна в действии», 5-е издание, но я считаю, что это ошибка.

Это GitHub книги.Я прибыл в гл. 3 tacos-jdbc источник кода

При отправке моего заказа появляется внезапная ошибка:

enter image description here

и таким образом на терминале:

2019-05-25 16: 58: 18.164 ОШИБКА 11777 --- [nio-8080-exec-7] org.thymeleaf.TemplateEngine: [THYMELEAF] [http-nio-8080-exec-7] Шаблон обработки исключительной ситуации "orderForm": во время синтаксического анализа произошла ошибка (template: "ресурс пути к классу [templates / orderForm.html]")

org.thymeleaf.exceptions.TemplateInputException: во время синтаксического анализа произошла ошибка (template: "ресурс пути к классу [templates / orderForm.html]")

enter image description here

OrderController:

@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>

Ответы [ 4 ]

1 голос
/ 31 мая 2019

Я исправил с помощью этого кода добавление 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>
0 голосов
/ 25 мая 2019

Я думаю, вы могли бы сделать это таким образом

@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";   
       }
    }
}
0 голосов
/ 27 мая 2019

Я думаю, что вы должны обработать отображение ошибок валидации во всех входных данных в файле 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.

0 голосов
/ 25 мая 2019

Вы используете th:object="${order}" в своем шаблоне orderForm, но 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:/");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...