Problem z wyświetleniem widoku formularza w Thymeleaf

0

Cześć,

W aplikacji założyłem że będę miał encję Address w której będę przechowywał zarówno adres stały jak i korespondencyjny.
Z wyświetleniem widoku pojedynczego adresu nie miałem problemu, ale kiedy przyszło mi przerobić program aby móc dodawać z formularza 2 rodzaje adresów, pojawiły się schody.
Sytuacja jest taka że po odpaleniu programu i przejściu do formularza dodawania adresów IntelliJ nie zgłasza żadnych błędów a formularz adresu nie wyświetla się na ekranie.
Poniżej kod:

Widok:

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Dodaj nową firmę</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

    <link rel="stylesheet" th:href="@{/webjars/bootstrap/4.4.1-1/css/bootstrap.min.css}" />

    <script th:src="@{/webjars/jquery/3.5.1/jquery.min.js}"></script>
    <script th:src="@{/webjars/bootstrap/4.4.1-1/js/bootstrap.min.js}"></script>

</head>
<body>
    <div style = "text-align: center;">
        <h1>Dodaj nowego pracownika do bazy danych</h1>
    </div>
    <form class="form-horizontal"  th:object="${employee}" th:action="@{/employees}"  th:method="post">
        <div class="container" style="margin-top:10mm;">
            <div class="row">
                <div class="col-sm">
                    <div style = "text-align: center;">
                        <h5>Dane osobowe</h5>
                    </div>
                    <div class="form-group">
                        <input type="text" class="form-control" th:field="*{name}"/>
                        <label class="control-label">Imię</label>
                        <div class="text-danger"><p th:if="${#fields.hasErrors('name')}" th:errors="*{name}"/></div>
                    </div>
                    <div class="form-group">
                        <input type="text" class="form-control" th:field="*{surname}"/>
                        <label class="control-label">Nazwisko</label>
                        <div class="text-danger"><p th:if="${#fields.hasErrors('surname')}" th:errors="*{surname}"/></div>
                    </div>
                    <div class="form-group">
                        <input type="text" class="form-control" th:field="*{position}"/>
                        <label class="control-label">Stanowisko</label>
                        <div class="text-danger"><p th:if="${#fields.hasErrors('position')}" th:errors="*{position}"/></div>
                    </div>
                    <div class="form-group">
                        <input type="number" class="form-control" th:field="*{age}"/>
                        <label class="control-label">Wiek</label>
                        <div class="text-danger"><p th:if="${#fields.hasErrors('age')}" th:errors="*{age}"/></div>
                    </div>
                    <div class="form-group">
                        <input type="text" class="form-control" th:field="*{nationality}"/>
                        <label class="control-label">Obywatelstwo</label>
                        <div class="text-danger"><p th:if="${#fields.hasErrors('nationality')}" th:errors="*{nationality}"/></div>
                    </div>
                </div>

                <div class="col-sm">
                    <div th:object="${listAddress}">
                        <div style = "text-align: center;">
                            <h5>Dane adresowe</h5>
                        </div>
                        <div style = "text-align: center;">
                            <h6>Adres stały</h6>
                        </div>

                        <div th:each="row, stat : ${listAddress.addresses}">
                            <div class="form-group">
                                <input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].type}"/>
                                <label class="control-label">Typ adresu</label>
<!--                                <div class="text-danger"><p th:if="${#fields.hasErrors('type')}" th:errors="*{type}"/></div>-->
                            </div>
                            <div class="form-group">
                                <input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].street}"/>
                                <label class="control-label">Ulica</label>
<!--                                <div class="text-danger"><p th:if="${#fields.hasErrors('street')}" th:errors="*{street}"/></div>-->
                            </div>
                            <div class="form-group">
                                <input type="number" class="form-control" th:field="*{addresses[__${stat.index}__].streetNr}"/>
                                <label class="control-label">Numer domu</label>
<!--                                <div class="text-danger"><p th:if="${#fields.hasErrors('streetNr')}" th:errors="*{streetNr}"/></div>-->
                            </div>
                            <div class="form-group">
                                <input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].flatNr}"/>
                                <label class="control-label">Numer mieszkania</label>
<!--                                <div class="text-danger"><p th:if="${#fields.hasErrors('flatNr')}" th:errors="*{flatNr}"/></div>-->
                            </div>
                            <div class="form-group">
                                <input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].postalCode}"/>
                                <label class="control-label">Kod pocztowy</label>
<!--                                <div class="text-danger"><p th:if="${#fields.hasErrors('postalCode')}" th:errors="*{postalCode}"/></div>-->
                            </div>
                            <div class="form-group">
                                <input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].city}"/>
                                <label class="control-label">Miasto</label>
<!--                                <div class="text-danger"><p th:if="${#fields.hasErrors('city')}" th:errors="*{city}"/></div>-->
                            </div>
                            <div class="form-group">
                                <input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].country}"/>
                                <label class="control-label">Kraj</label>
<!--                                <div class="text-danger"><p th:if="${#fields.hasErrors('country')}" th:errors="*{country}"/></div>-->
                            </div>
                        </div>
                    </div>
                   <div style = "text-align: right;">
                        <button type="submit" class="btn btn-primary btn-lg active center-block">ZAPISZ</button>
                    </div>
                </div>
            </div>
        </div>
    </form>
</body>
</html>

Controller:

    @RequestMapping("/new")
    public String addNewEmployee(Model model) {
        AddressesList listOfAddress = new AddressesList();
        ArrayList<Address> addressesArray = new ArrayList<>();
        listOfAddress.setAddresses(addressesArray);
        model.addAttribute("employee", new Employee()).addAttribute("listAddress", listOfAddress);

        return "new_employee_form";
    }

Klasa Lista adresów:

public class AddressesList {

    private List<Address> addresses;

    public AddressesList() {
    }

    public AddressesList(List<Address> addresses) {
        this.addresses = addresses;
    }

    public List<Address> getAddresses() {
        return addresses;
    }

    public void setAddresses(List<Address> addresses) {
        this.addresses = addresses;
    }
}

Klasa Adres:

public class Address {

    public Long idAddress;
    public Long idEmployee;
    public String type;
    public String street;
    public String streetNr;
    public Integer flatNr;
    public String postalCode;
    public String city;
    public String country;

    public Address() {
    }

    private Address(Long idEmployee, String type, String street, Integer flatNr, String streetNr, String postalCode, String city, String country) {
        this.idEmployee = idEmployee;
        this.type = type;
        this.street = street;
        this.streetNr = streetNr;
        this.flatNr = flatNr;
        this.postalCode = postalCode;
        this.city = city;
        this.country = country;
    }

    public static class AddressBuilder{
        private Long idAddress;
        private Long idEmployee;
        private String type;
        private String street;
        private String streetNumber;
        private Integer flatNr;
        private String postalCode;
        private String city;
        private String country;

        public AddressBuilder setIdEmployee(Long idEmployee) {
            this.idEmployee = idEmployee;
            return this;
        }

        public AddressBuilder setType(String type) {
            this.type = type;
            return this;
        }

        public AddressBuilder setStreet(String street) {
            this.street = street;
            return this;
        }

        public AddressBuilder setFlatNr(Integer flatNr) {
            this.flatNr = flatNr;
            return this;
        }

        public AddressBuilder setStreetNumber(String streetNumber) {
            this.streetNumber = streetNumber;
            return this;
        }

        public AddressBuilder setPostalCode(String postalCode) {
            this.postalCode = postalCode;
            return this;
        }

        public AddressBuilder setCity(String city) {
            this.city = city;
            return this;
        }

        public AddressBuilder setCountry(String country) {
            this.country = country;
            return this;
        }

        public Address build(){
            return new Address(idEmployee, type, street, flatNr, streetNumber, postalCode, city, country);
        }
    }

    public void setIdAddress(Long idAddress) {
        this.idAddress = idAddress;
    }

    public void setIdEmployee(Long idEmployee) {
        this.idEmployee = idEmployee;
    }

    public void setType(String type) {
        this.type = type;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public void setFlatNr(Integer flatNr) {
        this.flatNr = flatNr;
    }

    public void setStreetNr(String streetNr) {
        this.streetNr = streetNr;
    }

    public void setPostalCode(String postalCode) {
        this.postalCode = postalCode;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public Long getIdAddress() {
        return idAddress;
    }

    public Long getIdEmployee() {
        return idEmployee;
    }

    public String getType() {
        return type;
    }

    public String getStreet() {
        return street;
    }

    public Integer getFlatNr() {
        return flatNr;
    }

    public String getStreetNr() {
        return streetNr;
    }

    public String getPostalCode() {
        return postalCode;
    }

    public String getCity() {
        return city;
    }

    public String getCountry() {
        return country;
    }

    @Override
    public String toString() {
        return "Address{" +
                "idAddress=" + idAddress +
                ", idEmployee=" + idEmployee +
                ", type='" + type + '\'' +
                ", street='" + street + '\'' +
                ", flattNr=" + flatNr +
                ", streetNumber='" + streetNr + '\'' +
                ", postalCode='" + postalCode + '\'' +
                ", city='" + city + '\'' +
                ", country='" + country + '\'' +
                '}';
    }
}

I efekt na widoku - nie pokazuje się w ogóle formularz adresu w prawej kolumnie:

LINK

Szukam i szukam ale ciężko znaleźć przyczynę błędu bez komunikatu błędu...

0

Źle podszedłem do tematu. Kiedy zainicjalizowałem na próbę indeksy w tablicy ArrayList, formularz się pokazał, a nie o to mi chodzi.

    @RequestMapping("/new")
    public String addNewEmployee(Model model) {
        AddressesList listOfAddress = new AddressesList();
        ArrayList<Address> addressesArray = new ArrayList<Address>(2);
        addressesArray.add(0, new Address());
        addressesArray.add(1, new Address());
        listOfAddress.setAddresses(addressesArray);
        model.addAttribute("employee", new Employee()).addAttribute("listAddress", listOfAddress);

        return "new_employee_form";
    }

Chodzi o to aby formularz pokazał się od razu po otwarciu strony, abym wpisał do niego dane pracownika i dwa adresy stały i korespondencyjny i wysłał metodą POST.
Prosiłbym o nakierowanie, wskazówki jak to zrobić.

0
  1. Potrzebujesz dwie metody, jedna na GET jedna na POST
  2. W tej na GET dodajesz pusty obiekt do modelu
  3. W tej na POST odbierasz wypełniony formularz
0

To skupmy się na razie na GET
Pozmieniałem kod. Obecnie mój Controller wygląda tak:

    @GetMapping("/new")
    public String showCreateFormForEmployeeAndAddresses(Model model) {

        AddressRepository addressForm = new AddressRepository();

        for(int i = 1; i<=2; i++){
            addressForm.addAddress(new Address());
        }

        model.addAttribute("employee", new Employee()).addAttribute("form", addressForm);
        return "new_employee_form";
    }

w AddressRepository mam zadeklarowane pole z getterem, setterem, konstruktorem

public List<Address> addresses;

oraz metodę add:

    public void addAddress(Address address) {
        this.addresses.add(address);
    }

Widok natomiast wygląda tak:

<body>
    <div style = "text-align: center;">
        <h1>Dodaj nowego pracownika do bazy danych</h1>
    </div>
    <form class="form-horizontal"  th:object="${employee}" th:action="@{/employees}"  th:method="post">
        <div class="container" style="margin-top:10mm;">
            <div class="row">
                <div class="col-sm">
                    <div style = "text-align: center;">
                        <h5>Dane osobowe</h5>
                    </div>
                    <div class="form-group">
                        <input type="text" class="form-control" th:field="*{name}"/>
                        <label class="control-label">Imię</label>
                        <div class="text-danger"><p th:if="${#fields.hasErrors('name')}" th:errors="*{name}"/></div>
                    </div>
                    <div class="form-group">
                        <input type="text" class="form-control" th:field="*{surname}"/>
                        <label class="control-label">Nazwisko</label>
                        <div class="text-danger"><p th:if="${#fields.hasErrors('surname')}" th:errors="*{surname}"/></div>
                    </div>
                    <div class="form-group">
                        <input type="text" class="form-control" th:field="*{position}"/>
                        <label class="control-label">Stanowisko</label>
                        <div class="text-danger"><p th:if="${#fields.hasErrors('position')}" th:errors="*{position}"/></div>
                    </div>
                    <div class="form-group">
                        <input type="number" class="form-control" th:field="*{age}"/>
                        <label class="control-label">Wiek</label>
                        <div class="text-danger"><p th:if="${#fields.hasErrors('age')}" th:errors="*{age}"/></div>
                    </div>
                    <div class="form-group">
                        <input type="text" class="form-control" th:field="*{nationality}"/>
                        <label class="control-label">Obywatelstwo</label>
                        <div class="text-danger"><p th:if="${#fields.hasErrors('nationality')}" th:errors="*{nationality}"/></div>
                    </div>
                </div>
                <div class="col-sm">
                    <div th:object="${form}">
                        <div style = "text-align: center;">
                            <h5>Dane adresowe</h5>
                        </div>
                        <div style = "text-align: center;">
                            <h6>Adres stały</h6>
                        </div>

                        <div th:each="address, stat : *{addresses}">
                            <div class="form-group">
                                <input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].type}"/>
                                <label class="control-label">Typ adresu</label>
<!--                                <div class="text-danger"><p th:if="${#fields.hasErrors('type')}" th:errors="*{type}"/></div>-->
                            </div>
                            <div class="form-group">
                                <input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].street}"/>
                                <label class="control-label">Ulica</label>
<!--                                <div class="text-danger"><p th:if="${#fields.hasErrors('street')}" th:errors="*{street}"/></div>-->
                            </div>
                            <div class="form-group">
                                <input type="number" class="form-control" th:field="*{addresses[__${stat.index}__].streetNr}"/>
                                <label class="control-label">Numer domu</label>
<!--                                <div class="text-danger"><p th:if="${#fields.hasErrors('streetNr')}" th:errors="*{streetNr}"/></div>-->
                            </div>
                            <div class="form-group">
                                <input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].flatNr}"/>
                                <label class="control-label">Numer mieszkania</label>
<!--                                <div class="text-danger"><p th:if="${#fields.hasErrors('flatNr')}" th:errors="*{flatNr}"/></div>-->
                            </div>
                            <div class="form-group">
                                <input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].postalCode}"/>
                                <label class="control-label">Kod pocztowy</label>
<!--                                <div class="text-danger"><p th:if="${#fields.hasErrors('postalCode')}" th:errors="*{postalCode}"/></div>-->
                            </div>
                            <div class="form-group">
                                <input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].city}"/>
                                <label class="control-label">Miasto</label>
<!--                                <div class="text-danger"><p th:if="${#fields.hasErrors('city')}" th:errors="*{city}"/></div>-->
                            </div>
                            <div class="form-group">
                                <input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].country}"/>
                                <label class="control-label">Kraj</label>
<!--                                <div class="text-danger"><p th:if="${#fields.hasErrors('country')}" th:errors="*{country}"/></div>-->
                            </div>
                        </div>
                    </div>
                </div>
                <div style = "text-align: right;">
                    <button type="submit" class="btn btn-primary btn-lg active center-block">ZAPISZ</button>
                </div>
            </div>
        </div>
    </form>
</body>

Błąd z konsoli:

2020-05-12 19:05:32.378 ERROR 9672 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause

java.lang.NullPointerException: null
	at pl.kos.EmpSys.Domain.repository.AddressRepository.addAddress(AddressRepository.java:32) ~[classes/:na]
	at pl.kos.EmpSys.controllers.EmployeeController.showCreateFormForEmployeeAndAddresses(EmployeeController.java:64) ~[classes/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[na:na]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.33.jar:9.0.33]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1594) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at java.base/java.lang.Thread.run(Thread.java:830) ~[na:na]

Nie rozumiem co ten błąd oznacza.

1
Dazon napisał(a):

w AddressRepository mam zadeklarowane pole z getterem, setterem, konstruktorem

public List<Address> addresses;

oraz metodę add:

    public void addAddress(Address address) {
        this.addresses.add(address);
    }

Leci Ci nullpointer ponieważ próbujesz dodać obiekt do niezainicjalizowanej listy.
Czy masz gdziesz w repozytorium coś w stylu

addresses = new ArrayList<>()?

edit: Dodatkowo zanim zaczniesz zabawę z czymś do widoków (w tym wypadku thymeleaf) polecałbym ogarnięcie kodu javowego. Logika w kontrolerach,
klasa AddressesList, w której masz tylko listę adresów. To po co ta klasa?

AddressRepository addressForm = new AddressRepository();

Tworzenie repozytorium za każdym razem gdy przychodzi nowe żądanie? To jest proszenie się o problemy.
W tym wypadku nie korzystasz z bazy, więc strzelam, że z każdym requestem Twoja lista adresów w AddressRepository będzie wyglądać zupełnie inaczej. :)

2

Taki tip: popracuj z debugerem. Postawienie breakpointa w odpowiednie miejsce i wykrycie przyczyny NPE zajęłoby Ci o wiele mniej czasu niż napisanie tego postu ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1