Einstieg in Spring Boot, Teil 2 Views mit Thymeleaf erstellen

Autor / Redakteur: Dr. Dirk Koller / Stephan Augsten

Im ersten Teil unserer Serie zu Spring Boot haben wir ein Projekt aufgesetzt und dem Service eine erste Ausgabe entlockt. In diesem Beitrag geht es um Views, sprich Webseiten, die in Spring gerne mit Thymeleaf erstellt werden.

Firmen zum Thema

In Spring werden Views, sprich Webseiten, gerne mit Thymeleaf erstellt.
In Spring werden Views, sprich Webseiten, gerne mit Thymeleaf erstellt.
(Bild: Thymeleaf.org)

Thymeleaf ist eine serverseitige Template-Engine und ähnelt damit den bekannten Java Server Pages. Anders als diese können Thymeleaf-Templates aber ohne Probleme im Browser angezeigt und mit gängigen Designtools bearbeitet werden.

Thymeleaf bindet man ein, indem man in der POM-Datei des Maven-Projekts den Starter spring-boot-starter-thymeleaf als Abhängigkeit zufügt. Das lässt sich in der Spring Tool Suite (STS) über das Kontextmenü (Spring > Edit Starters) oder aber direkt im XML-Code erledigen:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

Eines der wichtigsten Features von Spring Boot ist die Autokonfiguration. Abhängig von eingebundenen Bibliotheken werden bestimmte Beans automatisch konfiguriert. Das Einbinden von spring-boot-starter-thymeleaf veranlasst die Konfiguration eines View Resolvers für Thymeleaf. Diese Komponente mappt View-Namen auf Thymeleaf-Templates, die unter src/main/ressources/templates gesucht werden.

Templates

Ein solches Template mit Namen „home.html“ legen wir dort nun mit folgendem Inhalt an:

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
   <title>Home</title>
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>   <p th:text="'Ich bin eine Thymeleaf-View!'" />
</body>
</html>

Einen Hinweis auf Thymeleaf gibt lediglich das Attribut „th:text“ mit der zugehörigen Namespace-Deklaration. Erwartungsgemäß dient es der Ausgabe von Text. Man kann die HTML-Datei mit einem Browser aus dem Dateisystem laden, sieht dann die Ausgabe allerdings nicht. Der Browser ignoriert das unbekannte Attribut „th:text“. Thymeleaf ist eine serverseitige Rendering-Technologie. Anders als bei clientseitigen Rendering-Frameworks wie Angular oder Vue.js müssen die Anweisungen vor dem Ausliefern an den Browser vom Server ausgewertet und ersetzt werden.

„Spring Boot“-Tutorial
Bildergalerie mit 16 Bildern

Dafür muss das Template vom Service zunächst einmal gefunden werden, der Name muss mitgeteilt werden. Dies geschieht im Rückgabewert einer Controller-Methode. Da der Rückgabewert nun als Schlüssel zum Auffinden des Templates dient (und nicht mehr wie in Teil 1 direkt in die HTTP-Response geschrieben werden soll) wird die Annotation @ResponseBody nicht mehr benötigt. Die Endung „.html“ wird als Default angenommen und kann weggelassen werden:

@Controllerpublic class PersonController {   @GetMapping("/")
   public String home() {
      return "home";
   }
}

Der Aufruf von http://localhost:8080 im Browser zeigt nun wie gewünscht die Webseite mit dem Text an.

Datenübergabe via Model

Um die View etwas interessanter zu gestalten, soll sie nun Daten aus dem Controller übergeben bekommen. Hier ist das übergebene Objekt eine Person:

package com.example.demo;public class Person {   private String firstname;
   private String lastname;
   public String getFirstname() {
      return firstname;
   }
   public void setFirstname(String firstname) {
      this.firstname = firstname;
   }
   public String getLastname() {
      return lastname;
   }
   public void setLastname(String lastname) {
      this.lastname = lastname;
   }
}

Zur Übergabe bekommt die Parameterliste der Methode ein implizites Model-Objekt zugefügt. Dieses Model wird von Spring Boot verwaltet, es wird automatisch an die View weiter gereicht. Dem Model können beliebige Datenobjekte zugefügt werden. Später werden die Daten wie Nachname und Vorname natürlich aus einer Datenbank geladen, hier werden sie jetzt aber erst mal hart kodiert.

@Controllerpublic class PersonController {   @GetMapping("/")
   public String home(Model model) {
      Person person = new Person();
      person.setFirstname("Max");
      person.setLastname("Mustermann");
      model.addAttribute(person);
      return "home";
   }
}

Im Thymeleaf-Template kann auf das Person-Objekt im Model mit Hilfe des Dollarzeichens und geschweifter Klammern zugegriffen werden.

   <span th:text="${person.firstname}" />
   <span th:text="${person.lastname}" />

Das funktioniert auch mit Listen. Wenn ein List-Objekt mit mehreren Personen im Model hinterlegt ist, lässt sich mit „th:each“ darüber iterieren:

<tbody>
   <tr th:each="person: ${personList}">
      <td th:text="${person.firstname}" />
      <td th:text="${person.lastname}" />
   </tr>
</tbody>

Der addAttribute()-Methode des Models lässt sich wahlweise als zweiter Parameter auch der Name des Objekts mitgeben, unter dem es im Template angesprochen werden soll. Wenn man ihn weglässt, wird der kleingeschriebene Name der Klasse, bei Listen mit einem angehängten „List“ verwendet (hier also person bzw. personList).

Formulare

Bisher wurden Daten vom Service zur Webseite übergeben. Das funktioniert natürlich auch in die andere Richtung, beispielsweise sollen in ein Formular eingegebene Daten zum Service übertragen werden. Das folgende Codestück gibt ein Beispiel:

<h1>Name</h1>
<form action="#" th:action="@{/}" th:object="${person}" method="post">
   <p>Vorname: <input type="text" th:field="*{firstname}" /></p>
   <p>Nachname: <input type="text" th:field="*{lastname}" /></p>
   <p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>

Formular mit Thymeleaf-Attributen.
Formular mit Thymeleaf-Attributen.
(Bild: Dr. Koller)

Das Thymeleaf-Attribut „th:action“ gibt an, welche URL aufgerufen werden soll. Mit „th:object“ wird das Objekt im Model spezifiziert, auf dessen Variablen dann im weiteren Verlauf mit „th:field“ zugegriffen wird.

Da es sich hier um einen Post-Request handelt, kommt serverseitig in einer weiteren Methode nun die Annotation @PostMapping zum Einsatz. Post-Requests auf / werden also in dieser Methode verarbeitet. Die Liste der Methodenargumente wird um die übergebene Person erweitert. Die Annotation @ModelAttribute davor bewirkt, dass das Argument aus dem Modell abgerufen wird.

@PostMapping("/")public String home(@ModelAttribute Person person, Model model) {   model.addAttribute(person);
   return "home";
}

An dieser Stelle ist es wichtig, sich noch mal den Ablauf der Requests zu vergegenwärtigen. Ruft man im Browser localhost:8080 auf, so ist dies ein GET-Request, der von der Controller-Methode mit dem GetMapping verarbeitet wird. In ihr wird die Person Max Mustermann erzeugt und in das Model gepackt.

„Spring Boot“-Tutorial
Bildergalerie mit 16 Bildern

Danach wird vom View Resolver die passende View mit dem Formular ermittelt, und mit dem Model befüllt. Klickt man im Formular auf den Submit-Button wird ein Post-Request ausgeführt, der den eingegebenen Namen der mit PostMapping annotierten Controller-Methode übergibt. Vorname und Nachname sind dann dort im Person-Objekt verfügbar.

Thymeleaf bietet natürlich noch viel mehr, wir haben hier nur an der Oberfläche gekratzt. Oft benötigt wird zum Beispiel „th:if“ zum Ein- oder Ausblenden von HTML-Elementen unter bestimmten Bedingungen. Nähere Informationen zu diesem und vielen anderen Attributen findet man in der Dokumentation zum Thymeleaf-Projekt.

Im nächsten Teil des Reihe befassen wir uns mit Datenbanken und Spring Boot. Bis dann!

(ID:46970305)

Über den Autor