Einstieg in Spring Boot, Teil 7 Formulareingaben validieren mit Spring Boot

Autor / Redakteur: Dr. Dirk Koller / Stephan Augsten

Nachdem wir im letzten Beitrag der Serie einen Blick auf die Architektur von Spring-Boot-Anwendungen geworfen haben, steht nun die Prüfung von Nutzereingaben auf syntaktische Korrektheit an.

Firma zum Thema

Eingaben auf einer Webseite sollten validiert und gemeldet werden, Spring Boot liefert hierfür ein Validation-Starter mit.
Eingaben auf einer Webseite sollten validiert und gemeldet werden, Spring Boot liefert hierfür ein Validation-Starter mit.
(Bild: geralt / Pixabay )

Das Validieren von Formulareingaben in Spring Boot erfolgt am einfachsten mit Hilfe des Bean Validation Frameworks, das seit 2017 in Form von Bean Validation 2.0 existiert. Das Einbinden des Frameworks erfolgt durch Zufügen der folgenden Starter-Abhängigkeit im POM:

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

Unter der Haube wird der Hibernate-Validator, die Referenzimplementierung der Validation API, hierfür genutzt. In der Spring Tool Suite (STS) kann das Modul alternativ direkt über ein Kontextmenü eingebunden werden: Rechtsklick auf pom.xml und dann Spring > Add Starters auswählen und die Abhängigkeit Validation zufügen. Das Validation-Framework ist damit einsatzbereit.

„Spring Boot“-Tutorial
Bildergalerie mit 18 Bildern

Als Beispielobjekt nehmen wir die aus den vorherigen Beiträgen bekannte Person, die nun noch um eine E-Mail-Adresse erweitert wird. Auf die Wiedergabe der zugehörigen set- und get-Methoden wird hier aus Platzgründen verzichtet, man kann sie in STS leicht via Source > Generate Getters and Setters… erzeugen lassen:

public class Person {   private String firstname;
   private String lastname;
   private String email;
   // ...
}

Die Validierung der Personeneigenschaften geschieht durch das Annotieren der entsprechenden Properties. Um beispielsweise zu gewährleisten, dass Vor- und Nachname gefüllt sind, wird für diese Eigenschaften die Annotation @NotBlank verwendet. Eine valide E-Mail lässt sich durch @Email erzwingen:

public class Person {   @NotBlank
   private String firstname;
   @NotBlank
   private String lastname;
   @Email
   private String email;
   // ...
}

Die Thymeleaf-View zum Absenden des Formulars ist ebenfalls schon aus einem vorherigen Beitrag bekannt, auch sie wird um die E-Mail-Adresse erweitert:

<!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>
   <h1>Benutzerdaten eingeben:</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>
         Email: <input type="text" th:field="*{email}" />
      </p>
      <p>
         <input type="submit" value="Submit" /> <input type="reset"
         value="Reset" />
      </p>
   </form>
</body>
</html>

In der Controller-Methode, die den Post-Request entgegennimmt, ist die Annotation @Valid vor dem Person-Objekt in der Argumentliste neu. Die Annotation wird benötigt, um den Validierungsmechanismus zu aktivieren:

@Controller
public class PersonController {
   @GetMapping("/")
   public String home(Model model) {
      Person person = new Person();
      model.addAttribute(person);
      return "home";
   }
   @PostMapping("/")
   public String home(@Valid Person person, Model model) {
      model.addAttribute(person);
      return "home";
   }
}

Versucht man nun, das Formular mit leerem Vor- oder Nachnamen oder einer ausgefüllten, aber ungültigen E-Mail-Adresse abzusenden, wird ein Fehler in der Konsole ausgegeben und eine Fehlerseite mit Stacktrace angezeigt. Exemplarisch wird hier eine solche Konsolenmeldung wiedergegeben:

Field error in object 'person' on field 'firstname': rejected value []; codes [NotBlank.person.firstname,NotBlank.firstname,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [person.firstname,firstname]; arguments []; default message [firstname]]; default message [darf nicht leer sein]

Der Inhalt der Meldung lässt darauf schließen, dass die Validierung funktioniert hat. Lediglich die Visualisierung des Ergebnisses lässt noch zu wünschen übrig. Der Benutzer soll vermutlich eher durch einen Hinweis auf der Seite mit dem Formular auf die Fehleingabe hingewiesen werden; nicht durch einen schwer lesbaren Stacktrace.

Die Fehlerseite mit dem Stracktrace wird man durch Zufügen des Interfaces BindingResult zur Argumentliste der Post-Methode los. Das Objekt kann nach eventuell vorhandenen Fehlern befragt werden. Hier im Beispiel werden die Fehler nur ausgegeben und danach zurück zum Formular geroutet, aber es ließe sich bei fehlerfreier Validierung auch mittels Redirect auf eine Erfolgsseite weiterleiten:

@PostMapping("/")
public String home(@Valid Person person, BindingResult bindingResult, Model model) {
   if (bindingResult.hasErrors()) {
      bindingResult.getAllErrors().stream().forEach(System.out::println);
   }
   model.addAttribute(person);
   return "home";
}

Die aufgetretenen Validierungsfehler werden an das HTML-Formular übergeben und können dort angezeigt werden:

<p th:if="${#fields.hasErrors('firstname')}" th:errors="*{firstname}"/>

Der Text der Nachricht („darf nicht leer sein“) kann dabei in der Validierungsannotation mit Hilfe des Attributs message angepasst werden:

public class Person {   @NotBlank(message = "Vorname muss angegeben werden")
   private String firstname;
}
„Spring Boot“-Tutorial
Bildergalerie mit 18 Bildern

Fehlerhafte Eingaben im Formular werden bemängelt.
Fehlerhafte Eingaben im Formular werden bemängelt.
(Bild: Dr. Koller)

Wie der Screenshot zeigt, ist das Ergebnis schon ganz brauchbar. In der Praxis würde man die betroffenen Textfelder und Fehlermeldungen vielleicht noch mittels CSS rot färben.

Neben den oben vorgestellten Annotationen existieren noch einige weitere, mit denen sich beispielsweise bestimmte Zahlenschwellwerte oder auch der Wert einer booleschen Variable überprüfen lassen:

  • @Email
  • @NotNull
  • @AssertTrue
  • @Size
  • @Min
  • @Max
  • @Email
  • @NotEmpty
  • @NotBlank

Details zur genauen Verwendung der Annotationen findet man in der Dokumentation zum Hibernate-Validator. Im achten Teil dieser Spring-Boot-Serie widmen wir uns der Konfiguration von Java Beans in Spring.

(ID:47107076)

Über den Autor