39 JSON-Generierung

In modernen Webanwendungen und RESTful Webservices ist JSON (JavaScript Object Notation) das häufigste Format für den Datenaustausch zwischen Client und Server. Spring Boot verwendet die Bibliothek Jackson, um Java-Objekte automatisch in JSON zu serialisieren und JSON-Daten in Java-Objekte zu deserialisieren. Die JSON-Generierung in Spring Boot ist einfach und erfordert oft nur minimale Konfiguration, da die meisten notwendigen Abhängigkeiten und Einstellungen bereits integriert sind.

In diesem Kapitel erklären wir, wie Spring Boot JSON-Objekte erzeugt und verarbeitet. Wir werden auch auf häufige Anpassungen, wie die Serialisierung und Deserialisierung von Java-Objekten in JSON, eingehen und Best Practices vorstellen.

39.1 Grundlagen der JSON-Generierung

Spring Boot generiert automatisch JSON-Daten, wenn ein Controller Java-Objekte zurückgibt. Dies geschieht dank der eingebauten Jackson-Bibliothek, die alle erforderlichen Konvertierungen zwischen Java-Objekten und JSON übernimmt.

39.1.1 Beispiel: Einfache JSON-Rückgabe in einem @RestController

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProductController {

    @GetMapping("/products")
    public Product getProduct() {
        return new Product(1L, "Laptop", 1200.00);
    }
}

In diesem Beispiel wird ein Product-Objekt automatisch als JSON-Antwort zurückgegeben, wenn die URL /products aufgerufen wird. Die Jackson-Bibliothek serialisiert das Product-Objekt in folgendes JSON-Format:

{
  "id": 1,
  "name": "Laptop",
  "price": 1200.00
}

39.1.2 Jackson als Standard-JSON-Bibliothek

Spring Boot verwendet standardmäßig Jackson zur Serialisierung und Deserialisierung von JSON-Daten. Jackson ist eine weit verbreitete und flexible JSON-Bibliothek in der Java-Welt, die leicht anpassbar ist. Sie können andere JSON-Bibliotheken wie Gson verwenden, indem Sie die Jackson-Abhängigkeit in Ihrer Anwendung durch eine andere Bibliothek ersetzen, jedoch wird Jackson in den meisten Fällen bevorzugt.

39.2 Serialisierung von Java-Objekten in JSON

Die Serialisierung ist der Prozess, bei dem ein Java-Objekt in ein JSON-Format umgewandelt wird, das an den Client gesendet werden kann. Spring Boot macht dies standardmäßig, indem es auf den Java-Klassen aufbaut, die die Datenstruktur definieren.

39.2.1 Beispiel: Einfache Serialisierung

Nehmen wir an, wir haben die folgende Product-Klasse:

public class Product {
    private Long id;
    private String name;
    private Double price;

    // Konstruktoren, Getter und Setter
    public Product(Long id, String name, Double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public Double getPrice() {
        return price;
    }
}

Wenn dieses Objekt durch einen Controller zurückgegeben wird, wird es von Spring Boot automatisch in JSON serialisiert, ohne dass zusätzliche Konfiguration erforderlich ist.

39.2.2 Anpassung der JSON-Serialisierung

In einigen Fällen möchten Sie die Serialisierung anpassen, indem Sie z.B. bestimmte Felder ausschließen, das Format ändern oder die Namen von Feldern anpassen.

39.2.2.1 Ausschließen von Feldern mit @JsonIgnore

Mit der Annotation @JsonIgnore können Sie festlegen, dass bestimmte Felder während der JSON-Serialisierung ignoriert werden sollen.

import com.fasterxml.jackson.annotation.JsonIgnore;

public class Product {
    private Long id;
    private String name;
    
    @JsonIgnore
    private Double price;

    // Konstruktoren, Getter und Setter
}

Das price-Feld wird nun bei der Serialisierung ignoriert und erscheint nicht im JSON-Output:

{
  "id": 1,
  "name": "Laptop"
}

39.2.2.2 Umbenennen von Feldern mit @JsonProperty

Mit der Annotation @JsonProperty können Sie die Namen der JSON-Felder ändern.

import com.fasterxml.jackson.annotation.JsonProperty;

public class Product {
    private Long id;

    @JsonProperty("product_name")
    private String name;

    private Double price;

    // Konstruktoren, Getter und Setter
}

Hier wird das name-Feld in product_name umbenannt:

{
  "id": 1,
  "product_name": "Laptop",
  "price": 1200.00
}

39.3 Deserialisierung von JSON in Java-Objekte

Deserialisierung ist der Prozess, bei dem JSON-Daten in Java-Objekte umgewandelt werden. In Spring Boot wird dies oft bei der Verarbeitung von POST- oder PUT-Anfragen verwendet, bei denen der Client JSON-Daten sendet, die in Java-Objekte umgewandelt werden müssen.

39.3.1 Beispiel: Deserialisierung eines JSON-Objekts

Ein @PostMapping-Beispiel, bei dem JSON-Daten in ein Product-Objekt deserialisiert werden:

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProductController {

    @PostMapping("/products")
    public Product createProduct(@RequestBody Product product) {
        // Das JSON wird in ein Product-Objekt umgewandelt
        return productService.saveProduct(product);
    }
}

Wenn ein Client JSON-Daten wie diese sendet:

{
  "id": 1,
  "name": "Laptop",
  "price": 1200.00
}

Spring Boot wandelt diese automatisch in ein Product-Objekt um.

39.4 Validierung von JSON-Daten

Sie können JSON-Daten validieren, bevor sie in Java-Objekte deserialisiert werden. Spring Boot bietet Unterstützung für die Bean Validation API, die Ihnen ermöglicht, Regeln für die Validierung von Objekten zu definieren.

39.4.1 Beispiel: Validierung eines JSON-Objekts

Verwenden Sie Annotationen wie @NotNull und @Min, um sicherzustellen, dass die JSON-Daten korrekt sind, bevor sie in ein Java-Objekt umgewandelt werden.

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

public class Product {

    private Long id;

    @NotNull(message = "Name darf nicht leer sein")
    private String name;

    @Min(value = 0, message = "Preis muss größer als 0 sein")
    private Double price;

    // Konstruktoren, Getter und Setter
}

In Kombination mit einem @PostMapping-Controller können Sie die Validierung aktivieren:

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProductController {

    @PostMapping("/products")
    public Product createProduct(@Validated @RequestBody Product product) {
        // Produkt wird nur erstellt, wenn die Validierung erfolgreich ist
        return productService.saveProduct(product);
    }
}

Wenn die Validierung fehlschlägt, gibt Spring Boot automatisch einen Fehlerstatus mit einer Beschreibung der Validierungsfehler zurück.

39.5 Umgang mit JSON im Kontext von Arrays und Listen

Häufig müssen mehrere Objekte gleichzeitig verarbeitet werden, was bedeutet, dass JSON-Arrays und Listen von Objekten gesendet oder empfangen werden müssen.

39.5.1 Beispiel: Verarbeitung einer Liste von Objekten

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RestController
public class ProductController {

    @PostMapping("/bulk-products")
    public List<Product> createProducts(@RequestBody List<Product> products) {
        // Verarbeitung einer Liste von Produkten
        return productService.saveAllProducts(products);
    }
}

Wenn ein JSON-Array wie folgt gesendet wird:

[
  {
    "id": 1,
    "name": "Laptop",
    "price": 1200.00
  },
  {
    "id": 2,
    "name": "Tablet",
    "price": 500.00
  }
]

Wird dieses automatisch in eine Liste von Product-Objekten umgewandelt.

39.6 JSON-Formatierung anpassen

Manchmal möchten Sie das Format des zurückgegebenen JSONs anpassen, z.B. durch Einrückungen oder die Veränderung von Zeit- und Datumsformaten. Dies kann durch die Konfiguration von Jackson erreicht werden.

39.6.1 Beispiel: Aktivieren der Pretty-Print-Funktion

Um das JSON mit Einrückungen und Zeilenumbrüchen auszugeben (Pretty-Print), können Sie die folgende Konfiguration in application.properties setzen:

spring.jackson.serialization.indent_output=true

39.6.2 Beispiel: Anpassen von Datumsformaten

Um das Standard-Datumsformat anzupassen, können Sie Jackson entsprechend konfigurieren:

import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;

public class Product {
    private Long id;
    private String name;

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    private Date releaseDate;

    // Konstruktoren, Getter und

 Setter
}

Hier wird das Datumsformat in yyyy-MM-dd geändert.

39.7 tl;dr

Spring Boot vereinfacht die Arbeit mit JSON durch die nahtlose Integration der Jackson-Bibliothek. Die automatische Serialisierung und Deserialisierung von Java-Objekten in JSON und umgekehrt erfolgt ohne großen Aufwand. Durch die Verwendung von Jackson-Anmerkungen können Entwickler die JSON-Generierung flexibel anpassen, um den spezifischen Anforderungen ihrer Anwendung gerecht zu werden. Ob einfache Objekte, Listen, Validierung oder benutzerdefinierte JSON-Formate – Spring Boot bietet leistungsstarke und intuitive Werkzeuge für die Arbeit mit JSON in RESTful Webservices.