Ошибка в приложении из Spring in Action

Всем доброго времени суток!

Некоторое время назад начал изучать Spring по книге Spring in action в которой целью и итогом обучения становится приложение для заказа Тако. На первых порах всё работало как надо, всё открывалось, пока не произошёл затык. При вызове страницы http://localhost:8080/design открывается страница с созданием своего рецепта, в конце есть кнопка для перехода на страницу оформления заказа. Но по нажатии кнопки "Отправить", она(страница) по какой-то причине не открывается(Вылетает ошибка 500(код и репорт приложу ниже), хотя и класс-контроллер и представление написаны по сути идентично с /design. Прошу помочь разобраться с проблемой, ибо уже бьюсь в эту стену неделю и мотивации заниматься танцами с бубном становится всё меньше. Заранее спасибо)

Что по итогу

введите сюда описание изображения

введите сюда описание изображения

введите сюда описание изображения

POM.xml

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.13</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>sia</groupId>
    <artifactId>taco-cloud</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>taco-cloud</name>
    <description>taco-cloud</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jetbrains</groupId>
            <artifactId>annotations</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>

          </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Контроллер нерабочей страницы

    package sia.tacocloud.web;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.support.SessionStatus;
import sia.tacocloud.TacoOrder;

@Slf4j
@Controller
@RequestMapping("/orders")
public class OrderController {

    @GetMapping("/current")
    public String orderForm(){
        return "orderForm";
    }

    @PostMapping
    public String processOrder(TacoOrder order, SessionStatus sessionStatus){
        log.info("Order submitted: {}", order);
        sessionStatus.setComplete();
        return "redirect:/";
    }
}

Виновница торжества

<!DOCTYPE html>
<html  xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Taco Cloud</title>
    <link rel="stylesheet" th:href="@{/styles.css}"/>
</head>

<body>

<form method="POST" th:action="@{/orders}" th:object="${tacoOrder}">
    <h1>Order your taco creations!</h1>

    <img th:src="@{/images/order.png}" width="200" height="300">
        <h3>Your tacos in this order:</h3>
        <a th:href="@{/design}" id="another">Design another taco</a><br/>
    <ul>
        <li th:each="taco : ${tacoOrder.tacos}">
            <span th:text="${taco.name}">taco name</span>
        </li>
    </ul>

    <h3>Deliver my taco masterpieces to...</h3>
    <label for="deliveryName">Name: </label>
    <input type="text" th:field="*{deliveryName}" id="deliveryName"/>
    <br/>

    <label for="deliveryStreet"> Street address: </label>
    <input type="text" th:field="*{deliveryStreet}" id="deliveryStreet"/>
    <br/>

    <label for="deliveryCity">City: </label>
    <input type="text" th:field="*{deliveryCity}" id="deliveryCity"/>
    <br/>

    <label for="deliveryState">State: </label>
    <input type="text" th:field="*{deliveryState}" id="deliveryState"/>
    <br/>

    <label for="deliveryZip">Zip code: </label>
    <input type="text" th:field="*{deliveryZip}" id="deliveryZip">
    <br/>

    <h3>Here's how I'll pay...</h3>
    <label for="ccNumber">Credit Card #: </label>
    <input type="text" th:field="*{ccNumber}" id="ccNumber"/>
    <br/>

    <label for="ccCVV">CVV: </label>
    <input type="text" th:field="*{ccCVV}" id="ccCVV"/>
    <br/>

    <input type="submit" value="Submit Order">

</form>
</body>
</html>

Поля заказа

package sia.tacocloud;

import java.util.List;
import java.util.ArrayList;
import lombok.Data;
@Data
public class TacoOrder {
    private String deliveryName;
    private String deliveryStreet;
    private String deliveryCity;
    private String deliveryState;
    private String deliveryZip;
    private String ccNumber;
    private String ccExpiration;
    private String ccCVV;
    private List<Taco> tacos = new ArrayList<>();
    public void addTaco(Taco taco) {
        this.tacos.add(taco);
    }
}

После добавления TacoOrder.tacos в модель, лог укоротился до вот этого

введите сюда описание изображения


Ответы (1 шт):

Автор решения: kio

Ошибка возникает в следующей строке (упоминание в логе - ("orderForm" - line 20, col 13))

<span th:text="${taco.name}">taco name</span>

Скорее всего из за того что в классе TacoOrder отсутствует метод getTacos()

package tacos;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class TacoOrder implements Serializable {
  private static final long serialVersionUID = 1L;
  private Long id;
  private Date placeAt;
  private String deliveryName;
  private String deliveryStreet;
  private String deliveryCity;
  private String deliveryState;
  private String deliveryZip;
  private String ccNumber;
  private String ccExpiration;
  private String ccCVV;
  
  private List<Taco> tacos = new ArrayList<>();

public void addTaco(Taco taco) {
    this.tacos.add(taco);
}

public List<Taco> getTacos(){
    return this.tacos;
}

public String getDeliveryName() {
    return deliveryName;
}

public void setDeliveryName(String deliveryName) {
    this.deliveryName = deliveryName;
}

public String getDeliveryCity() {
    return deliveryCity;
}

public void setDeliveryCity(String deliveryCity) {
    this.deliveryCity = deliveryCity;
}

public String getDeliveryStreet() {
    return deliveryStreet;
}

public void setDeliveryStreet(String deliveryStreet) {
    this.deliveryStreet = deliveryStreet;
}

public String getDeliveryState() {
    return deliveryState;
}

public void setDeliveryState(String deliveryState) {
    this.deliveryState = deliveryState;
}

public String getDeliveryZip() {
    return deliveryZip;
}

public void setDeliveryZip(String deliveryZip) {
    this.deliveryZip = deliveryZip;
}

public String getCcNumber() {
    return ccNumber;
}

public void setCcNumber(String ccNumber) {
    this.ccNumber = ccNumber;
}

public String getCcExpiration() {
    return ccExpiration;
}

public void setCcExpiration(String ccExpiration) {
    this.ccExpiration = ccExpiration;
}

public String getCcCVV() {
    return ccCVV;
}

public void setCcCVV(String ccCVV) {
    this.ccCVV = ccCVV;
}

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public Date getPlaceAt() {
    return placeAt;
}

public void setPlaceAt(Date placeAt) {
    this.placeAt = placeAt;
}
}

Из-за этого при попытке получения {taco.name} вываливается ошибка. Она упоминается на последнем скриншоте.

→ Ссылка