Jakarta Bean Validation, die Inputvalidierungsmöglichkeiten von REST APIs in Java

24.02.2022

Aktuell existieren eine Vielzahl von Inputvalidierungsmöglichkeiten, dabei kann man leicht den Überblick verlieren. Die Jakarta Bean Validation ist eine empfehlenswerte Inputvalidierung von REST APIs in Java.

Inputvalidierung

Jeder Entwickler weiß, dass die Inputvalidierung sehr relevant ist. Sie ist eine große Gegenmaßnahme für einige Sicherheitsprobleme wie Injektion-Angriffe oder Cross-Side Scripting. Zusätzlich kontrolliert sie auch, ob die Eingaben verarbeitet werden können.

In der Praxis wird sie jedoch oft vernachlässigt und nur rudimentäre Inputvalidierungen werden durchgeführt.

Selbst bei internationalen Großkonzernen, wie zum Beispiel Apple, treten in diesem Bereich Fehler auf die enorme Auswirkungen auf bestimmte Nutzer haben. Die Nutzerin Rachel True konnte fünf Monate lang nicht auf ihren iCloud Account zugreifen, da ihr Nachname „True“ nicht als Zeichenkette, sondern als Boolean interpretiert wurde. Ein solcher Fehler hätte durch eine korrekt durchgeführte Inputvalidierung vermieden werden können.

Thesis

Meine Thesis beschäftigt sich mit dem Vergleich von Inputvalidierungen.

Den meisten Entwicklerinnen und Entwicklern im Java Umfeld ist das Framework Jakarta Bean Validation bekannt. Jedoch werden die meisten Inputvalidierungen ohne ein Framework umgesetzt.

In meiner Thesis habe ich 3 Inputvalidierungsmöglichkeiten Jakarta Bean Validation, JSON-Schema und XML-Schema anhand 4 Kriterien untersucht:

  • Die Implementierung
    • Hierbei ist zu beachten, dass die Implementierung schnell und mit wenig Aufwand umgesetzt werden kann.
  • Der Aufwand und die Struktur
    • Hierbei gilt der Aufwand hinsichtlich der Erstellung eines Constraint. Dies hängt zusätzlich von der Komplexität der Struktur ab das Constraint abzubilden.
  • Die Möglichkeiten
    • Dieses Kriterium untersucht, wie viele Möglichkeiten zur Validierung der Eingaben eine Inputvalidierung anbietet.
  • Die Fehlermeldung
    •  Die Fehlermeldung bezieht sich auf die Behandlung einer nicht validen Eingabe. Hierbei ist zu beachten, welche Rückgabe der Nutzer erhält.

Anhand der erwähnten Kriterien wurde eine Nutzwertanalyse mit den auserwählten Inputvalidierungsmöglichkeiten durchgeführt.

Die Jakarta Bean Validation hat im Vergleich zu den weiteren Inputvalidierungsmöglichkeiten, JSON-Schema und XML-Schema, diese Kriterien am weitesten erfüllt. In den Kriterien Möglichkeiten, Aufwand und Struktur hat es die höchste Punktzahl erreicht, da die Umsetzung mit wenig Aufwand verbunden und die Struktur für einen Java-Entwickler bereits bekannt ist. Aufgrund der Tatsache, dass die Validierungen in Java geschrieben werden, hat die Jakarta Bean Validation die gleichen Möglichkeiten, wie eine Validierung ohne Framework.

Das JSON-Schema schneidet besser ab, als das XML-Schema. Dies liegt zum größten Teil daran, dass das XML-Schema eine komplexe Struktur besitzt. Dies zeigt sich in der Bewertung des Kriterium Aufwand und Struktur. Hier hat das XML-Schema die niedrigste Bewertung.

Jakarta Bean Validation

Die Jakarta Bean Validation ist der Standard für Validierungen in Java. Zusätzlich ist es sehr gut in Spring Boot integriert.

Im Folgenden wird ein kleines Beispiel erläutert, dass zeigt, wie einfach die Anwendung von Jakarta Bean Validation in Spring ist.

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

Die Spring-boot-starter-validation dependency integriert die Hibernate Referenzimplementierung von Jakarta Bean Validation in Spring Boot.

@PostMapping("/addCustomer")
public void add(@RequestBody @Valid Customer customer) {
}

Die Umsetzung der Validierung wird direkt in der REST Schnittstelle im Controller durch eine einfache Annotation @Valid umgesetzt.

Somit erspart man sich ein Validator-Objekt mit einer ValidatorFactory zu bauen.

@Min(value = 18, message = "Age should not be less than 18")
private int age;

Die Anwendung des Constraint wird ebenfalls durch Annotation auf das zugehörige Java Bean umgesetzt.

Die Jakarta Bean Validation wendet die Validierung auf JavaBeans, Felder, Klassen und Properties an. Die Constraints werden auf Typen deklariert und gegen Instanzen oder Graphen von Instanzen ausgewertet. Zusätzlich können die Constraints auf Methoden und Konstruktoren angewendet werden, wobei der Rückgabewert und die Parameter die zu validierenden Elemente sind.

Das Constraint @Min ist ein Build-in Constraint, welches von Jakarta Bean Validation vordefiniert ist. Insgesamt besitzt Jakarta Bean Validation 22 Build-in Constraints und die Referenzimplementierung Hibernate definiert zusätzlich noch 24 weitere detaillierte Build-in Constraints.

Das darauffolgende Beispiel zeigt die Erstellung einer Cross-Field Validation, bei der ein Constraint selbst definiert wird mit dem Namen ItalyTax. Dieses Constraint überprüft das Land einer Kundenadresse und wenn dieses Land Italien ist, braucht der Kunde eine zugehörige Steuernummer.

@Target(ElementType.TYPE)
@Retention(RUNTIME)
@Constraint(validatedBy = { ItalyTaxValidator.class })
public @interface ItalyTax {

    String message() default "if your country is Italy you need a syntactic valid vatID"
            + "if your country is not Italy, your vatID must be empty";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };
}

Um Constraints selbst zu definieren, wird eine Annotation erstellt. Das Interface ItalyTax hat drei Annotations, einmal das Target, welches angibt, auf was die Annotation angewendet werden kann. Die @Retention Annotation gibt an, ob es zu Compilerzeit oder zur Laufzeit ausgeführt wird. Und die @Constraints verweist auf die Validierungsklasse, in der die Logik der Validierung liegt.

public class ItalyTaxValidator implements
        ConstraintValidator<ItalyTax, Address> {

    @Override
    public void initialize(final ItalyTax constraint) {
    }

    @Override
    public boolean isValid(Address address,
            ConstraintValidatorContext constraintValidatorContext) {
        //validation logic
        return true;
    }
}

Die Validierungsklasse ItalyTaxValidator implementiert die Schnittstelle ConstraintValidator und übergibt die Annotation und die Klasse auf welche die Annotation angewendet wird. Diese Klasse überschreibt zwei Methoden, die Initialize-Methode in dem Parameter initialisiert werden können und die isValid-Methode, wo die eigentliche Validierungslogik liegt.

 

Fazit

Mit diesem kleinen Beispiel wird sichtbar, wie schnell Validierungen mit wenig Aufwand in Spring eingearbeitet werden können. Zusätzlich bietet die Jakarta Bean Validation an, Constraints selbst zu definieren, die einer selbst geschriebenen Validierung gleicht. Daher kann die Jakarta Bean Validation im Java Kontext nur empfohlen werden.

Mehr über Java Programmierung erfahren

Zurück zur Übersicht

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

*Pflichtfelder

*