Konfigurieren des ObjectMapper in Java, um unbekannte Eigenschaften in JSON zu ignorieren

JavaJavaBeginner
Jetzt üben

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In der Java-Entwicklung ist die Arbeit mit JSON-Daten eine gängige Anforderung. Die Klasse ObjectMapper aus der Jackson-Bibliothek ist ein leistungsstarkes Werkzeug für die Konvertierung zwischen Java-Objekten und JSON. Bei der Verarbeitung von JSON-Daten können jedoch Eigenschaften auftreten, die in Ihren Java-Klassen nicht definiert sind. Dies kann während der Deserialisierung zu Ausnahmen führen.

Dieses Lab führt Sie durch die Konfiguration des ObjectMapper, um unbekannte Eigenschaften in JSON-Daten zu ignorieren. Sie lernen, wie Sie JSON-Daten auf elegante Weise handhaben und Ihre Anwendungen robuster gestalten, wenn Sie mit externen Datenquellen arbeiten, die sich im Laufe der Zeit ändern können.

Grundlagen von JSON und ObjectMapper

Bevor wir uns damit befassen, wie man mit unbekannten Eigenschaften umgeht, wollen wir zunächst verstehen, was JSON ist und wie man den Jackson ObjectMapper in Java verwendet.

Was ist JSON?

JSON (JavaScript Object Notation) ist ein leichtgewichtiges Datenaustauschformat, das für Menschen leicht zu lesen und zu schreiben und für Maschinen leicht zu parsen und zu generieren ist. Es besteht aus Schlüssel-Wert-Paaren und wird häufig für die Übertragung von Daten zwischen Webanwendungen und Servern verwendet.

Hier ist ein einfaches Beispiel für ein JSON-Objekt:

{
  "name": "John Doe",
  "age": 30,
  "email": "[email protected]"
}

Einführung in Jackson ObjectMapper

Die Jackson-Bibliothek ist eine der beliebtesten JSON-Verarbeitungsbibliotheken in Java. Die Klasse ObjectMapper ist die zentrale Komponente von Jackson, die Funktionalität zur Konvertierung zwischen Java-Objekten und JSON bereitstellt.

Lassen Sie uns eine einfache Java-Klasse erstellen und den ObjectMapper verwenden, um sie in und aus JSON zu konvertieren.

Erstellen Sie zuerst eine Person-Klasse, indem Sie die folgenden Schritte ausführen:

  1. Öffnen Sie die WebIDE und navigieren Sie zur Explorer-Ansicht
  2. Erstellen Sie eine neue Datei unter ~/project/src/main/java/com/labex/json/Person.java
  3. Fügen Sie der Datei den folgenden Code hinzu:
package com.labex.json;

public class Person {
    private String name;
    private int age;

    // Default constructor needed for Jackson
    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Getters and setters
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

Erstellen wir nun eine Java-Klasse, um zu demonstrieren, wie man den ObjectMapper verwendet:

  1. Erstellen Sie eine neue Datei unter ~/project/src/main/java/com/labex/json/ObjectMapperDemo.java
  2. Fügen Sie der Datei den folgenden Code hinzu:
package com.labex.json;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;

public class ObjectMapperDemo {
    public static void main(String[] args) {
        try {
            // Create a Person object
            Person person = new Person("John Doe", 30);

            // Create an ObjectMapper instance
            ObjectMapper objectMapper = new ObjectMapper();

            // Serialize Person object to JSON string
            String jsonString = objectMapper.writeValueAsString(person);
            System.out.println("Serialized to JSON: " + jsonString);

            // Deserialize JSON string back to Person object
            Person deserializedPerson = objectMapper.readValue(jsonString, Person.class);
            System.out.println("Deserialized from JSON: " + deserializedPerson);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Kompilieren und führen wir diese Klasse nun aus:

  1. Öffnen Sie ein Terminal in der WebIDE
  2. Navigieren Sie zum Projektverzeichnis, falls Sie sich noch nicht dort befinden:
    cd ~/project
  3. Kompilieren und führen Sie die Klasse aus:
    mvn compile exec:java -Dexec.mainClass="com.labex.json.ObjectMapperDemo"

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

Serialized to JSON: {"name":"John Doe","age":30}
Deserialized from JSON: Person{name='John Doe', age=30}

Dies demonstriert die grundlegende Funktionalität des ObjectMapper:

  • Serialisierung: Konvertierung von Java-Objekten in JSON-Strings
  • Deserialisierung: Konvertierung von JSON-Strings zurück in Java-Objekte

Im nächsten Schritt werden wir untersuchen, was passiert, wenn das JSON Eigenschaften enthält, die in unserer Java-Klasse nicht definiert sind, und wie man damit umgeht.

Das Problem unbekannter Eigenschaften

In der realen Welt entwickeln sich JSON-Daten oft im Laufe der Zeit weiter. APIs können neue Felder hinzufügen, oder verschiedene Systeme können zusätzliche Informationen enthalten. Wenn Sie JSON mit Eigenschaften erhalten, die nicht mit Ihrer Java-Klasse übereinstimmen, ist das Standardverhalten von Jackson, eine Ausnahme auszulösen.

Sehen wir uns dieses Problem in Aktion an:

  1. Erstellen Sie eine neue Datei unter ~/project/src/main/java/com/labex/json/UnknownPropertiesDemo.java
  2. Fügen Sie der Datei den folgenden Code hinzu:
package com.labex.json;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;

public class UnknownPropertiesDemo {
    public static void main(String[] args) {
        try {
            // Create a JSON string with an extra property not in our Person class
            String jsonWithExtraProperty = "{\"name\":\"John Doe\",\"age\":30,\"email\":\"[email protected]\"}";

            // Create an ObjectMapper instance
            ObjectMapper objectMapper = new ObjectMapper();

            System.out.println("Attempting to deserialize JSON with an extra 'email' property...");

            // Try to deserialize the JSON into a Person object
            Person person = objectMapper.readValue(jsonWithExtraProperty, Person.class);

            // This line won't be reached if an exception occurs
            System.out.println("Successfully deserialized: " + person);

        } catch (Exception e) {
            System.out.println("Error occurred: " + e.getMessage());
        }
    }
}
  1. Kompilieren und führen Sie diese Klasse aus:
    cd ~/project
    mvn compile exec:java -Dexec.mainClass="com.labex.json.UnknownPropertiesDemo"

Sie sollten eine Fehlerausgabe ähnlich der folgenden sehen:

Attempting to deserialize JSON with an extra 'email' property...
Error occurred: Unrecognized field "email" (class com.labex.json.Person), not marked as ignorable (2 known properties: "name", "age"])

Dieser Fehler tritt auf, weil unsere Person-Klasse keine email-Eigenschaft hat, die JSON-Zeichenkette aber schon. Standardmäßig löst der ObjectMapper von Jackson eine Ausnahme aus, wenn er Eigenschaften findet, die er nicht erkennt.

In vielen realen Szenarien möchten wir, dass unsere Anwendung flexibler ist und solche Situationen elegant handhabt. Hier wird die Konfiguration des ObjectMapper zum Ignorieren unbekannter Eigenschaften nützlich.

Konfigurieren des ObjectMapper zum Ignorieren unbekannter Eigenschaften

Nachdem wir das Problem verstanden haben, wollen wir lernen, wie man den ObjectMapper so konfiguriert, dass er unbekannte Eigenschaften ignoriert, anstatt Ausnahmen auszulösen.

Es gibt zwei Hauptmöglichkeiten, den ObjectMapper so zu konfigurieren, dass er unbekannte Eigenschaften ignoriert:

  1. Verwendung der configure()-Methode mit DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
  2. Verwendung von Annotationen in Ihren Java-Klassen

Lassen Sie uns beide Ansätze implementieren:

Methode 1: Verwendung der configure()-Methode

Diese Methode konfiguriert die ObjectMapper-Instanz so, dass alle unbekannten Eigenschaften für alle deserialisierten Klassen ignoriert werden.

  1. Erstellen Sie eine neue Datei unter ~/project/src/main/java/com/labex/json/IgnoreUnknownDemo.java
  2. Fügen Sie der Datei den folgenden Code hinzu:
package com.labex.json;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;

public class IgnoreUnknownDemo {
    public static void main(String[] args) {
        try {
            // Create a JSON string with an extra property not in our Person class
            String jsonWithExtraProperty = "{\"name\":\"John Doe\",\"age\":30,\"email\":\"[email protected]\"}";

            // Create an ObjectMapper instance
            ObjectMapper objectMapper = new ObjectMapper();

            // Configure ObjectMapper to ignore unknown properties
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

            System.out.println("Attempting to deserialize JSON with an extra 'email' property...");

            // Deserialize the JSON into a Person object
            Person person = objectMapper.readValue(jsonWithExtraProperty, Person.class);

            // This should now work without throwing an exception
            System.out.println("Successfully deserialized: " + person);

        } catch (Exception e) {
            System.out.println("Error occurred: " + e.getMessage());
        }
    }
}
  1. Kompilieren und führen Sie diese Klasse aus:
    cd ~/project
    mvn compile exec:java -Dexec.mainClass="com.labex.json.IgnoreUnknownDemo"

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

Attempting to deserialize JSON with an extra 'email' property...
Successfully deserialized: Person{name='John Doe', age=30}

Beachten Sie, dass die Deserialisierung jetzt erfolgreich ist und die email-Eigenschaft einfach ignoriert wird. Unsere Anwendung funktioniert weiterhin trotz der zusätzlichen Eigenschaft im JSON.

Methode 2: Verwendung von Annotationen

Wenn Sie eine feinere Kontrolle wünschen, können Sie Jackson-Annotationen verwenden, um das Verhalten auf Klassenebene festzulegen.

  1. Erstellen Sie eine neue Datei unter ~/project/src/main/java/com/labex/json/PersonWithAnnotation.java
  2. Fügen Sie der Datei den folgenden Code hinzu:
package com.labex.json;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class PersonWithAnnotation {
    private String name;
    private int age;

    // Default constructor needed for Jackson
    public PersonWithAnnotation() {
    }

    public PersonWithAnnotation(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Getters and setters
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "PersonWithAnnotation{name='" + name + "', age=" + age + "}";
    }
}
  1. Erstellen Sie nun eine Demo-Klasse, um diesen Ansatz zu testen:
  2. Erstellen Sie eine neue Datei unter ~/project/src/main/java/com/labex/json/AnnotationDemo.java
  3. Fügen Sie der Datei den folgenden Code hinzu:
package com.labex.json;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;

public class AnnotationDemo {
    public static void main(String[] args) {
        try {
            // Create a JSON string with an extra property
            String jsonWithExtraProperty = "{\"name\":\"John Doe\",\"age\":30,\"email\":\"[email protected]\"}";

            // Create an ObjectMapper instance (no special configuration needed)
            ObjectMapper objectMapper = new ObjectMapper();

            System.out.println("Attempting to deserialize JSON with an extra 'email' property...");

            // Deserialize the JSON into a PersonWithAnnotation object
            PersonWithAnnotation person = objectMapper.readValue(jsonWithExtraProperty, PersonWithAnnotation.class);

            // This should work without throwing an exception
            System.out.println("Successfully deserialized: " + person);

        } catch (Exception e) {
            System.out.println("Error occurred: " + e.getMessage());
        }
    }
}
  1. Kompilieren und führen Sie diese Klasse aus:
    cd ~/project
    mvn compile exec:java -Dexec.mainClass="com.labex.json.AnnotationDemo"

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

Attempting to deserialize JSON with an extra 'email' property...
Successfully deserialized: PersonWithAnnotation{name='John Doe', age=30}

Die Annotation @JsonIgnoreProperties(ignoreUnknown = true) weist Jackson an, beim Deserialisieren von JSON in eine Instanz dieser Klasse alle unbekannten Eigenschaften zu ignorieren. Dieser Ansatz ist gezielter als die Konfiguration des gesamten ObjectMapper.

Praktische Anwendungen und reale Anwendungsfälle

Nachdem Sie verstanden haben, wie man den ObjectMapper so konfiguriert, dass er unbekannte Eigenschaften ignoriert, wollen wir einige praktische Anwendungen und reale Szenarien untersuchen, in denen diese Funktion nützlich ist.

1. Nutzung von APIs von Drittanbietern

Bei der Integration mit externen APIs haben Sie oft keine Kontrolle über Änderungen an deren Antwortformat. Durch die Konfiguration des ObjectMapper zum Ignorieren unbekannter Eigenschaften kann Ihre Anwendung weiterhin funktionieren, selbst wenn die API neue Felder hinzufügt.

Lassen Sie uns ein einfaches Beispiel erstellen, das die Nutzung einer Wetter-API simuliert:

  1. Erstellen Sie eine neue Datei unter ~/project/src/main/java/com/labex/json/WeatherData.java
  2. Fügen Sie der Datei den folgenden Code hinzu:
package com.labex.json;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class WeatherData {
    private String city;
    private double temperature;
    private int humidity;

    // Default constructor needed for Jackson
    public WeatherData() {
    }

    // Getters and setters
    public String getCity() {
        return city;
    }

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

    public double getTemperature() {
        return temperature;
    }

    public void setTemperature(double temperature) {
        this.temperature = temperature;
    }

    public int getHumidity() {
        return humidity;
    }

    public void setHumidity(int humidity) {
        this.humidity = humidity;
    }

    @Override
    public String toString() {
        return "WeatherData{" +
                "city='" + city + '\'' +
                ", temperature=" + temperature +
                ", humidity=" + humidity +
                '}';
    }
}
  1. Erstellen Sie eine neue Datei unter ~/project/src/main/java/com/labex/json/WeatherApiConsumer.java
  2. Fügen Sie der Datei den folgenden Code hinzu:
package com.labex.json;

import com.fasterxml.jackson.databind.ObjectMapper;

public class WeatherApiConsumer {
    public static void main(String[] args) {
        try {
            // Create an ObjectMapper
            ObjectMapper objectMapper = new ObjectMapper();

            // Simulate an initial API response with just the basics
            String initialApiResponse = "{\"city\":\"New York\",\"temperature\":72.5,\"humidity\":65}";

            // Parse the response
            WeatherData weatherData = objectMapper.readValue(initialApiResponse, WeatherData.class);
            System.out.println("Initial weather data: " + weatherData);

            // Now simulate the API adding new fields in a future version
            String updatedApiResponse =
                "{\"city\":\"New York\",\"temperature\":72.5,\"humidity\":65," +
                "\"wind_speed\":10.2,\"pressure\":1013.25,\"forecast\":\"sunny\"}";

            // Parse the updated response with the same object model
            WeatherData updatedWeatherData = objectMapper.readValue(updatedApiResponse, WeatherData.class);
            System.out.println("Updated weather data (with ignored fields): " + updatedWeatherData);

            // Notice how our application continues to work without changes to our model

        } catch (Exception e) {
            System.out.println("Error occurred: " + e.getMessage());
        }
    }
}
  1. Kompilieren und führen Sie diese Klasse aus:
    cd ~/project
    mvn compile exec:java -Dexec.mainClass="com.labex.json.WeatherApiConsumer"

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

Initial weather data: WeatherData{city='New York', temperature=72.5, humidity=65}
Updated weather data (with ignored fields): WeatherData{city='New York', temperature=72.5, humidity=65}

Beachten Sie, wie unsere Anwendung weiterhin mit der aktualisierten API-Antwort funktioniert, obwohl diese zusätzliche Felder enthält, die unsere WeatherData-Klasse nicht definiert.

2. Umgang mit verschiedenen API-Versionen

Ein weiteres häufiges Szenario ist, wenn Sie mehrere Versionen einer API mit demselben Client-Code unterstützen müssen:

  1. Erstellen Sie eine neue Datei unter ~/project/src/main/java/com/labex/json/ApiVersionDemo.java
  2. Fügen Sie der Datei den folgenden Code hinzu:
package com.labex.json;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ApiVersionDemo {
    public static void main(String[] args) {
        try {
            // Create an ObjectMapper that ignores unknown properties
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

            // API v1 response
            String apiV1Response = "{\"name\":\"John Doe\",\"age\":30}";

            // API v2 response with additional fields
            String apiV2Response =
                "{\"name\":\"John Doe\",\"age\":30,\"email\":\"[email protected]\"," +
                "\"address\":\"123 Main St\",\"phone\":\"555-1234\"}";

            // We can use the same Person class for both versions
            System.out.println("Parsing API v1 response:");
            Person personV1 = objectMapper.readValue(apiV1Response, Person.class);
            System.out.println(personV1);

            System.out.println("\nParsing API v2 response with the same class:");
            Person personV2 = objectMapper.readValue(apiV2Response, Person.class);
            System.out.println(personV2);

            // Both work fine with our simple Person class

        } catch (Exception e) {
            System.out.println("Error occurred: " + e.getMessage());
        }
    }
}
  1. Kompilieren und führen Sie diese Klasse aus:
    cd ~/project
    mvn compile exec:java -Dexec.mainClass="com.labex.json.ApiVersionDemo"

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

Parsing API v1 response:
Person{name='John Doe', age=30}

Parsing API v2 response with the same class:
Person{name='John Doe', age=30}

Dieses Beispiel zeigt, wie die Konfiguration des ObjectMapper zum Ignorieren unbekannter Eigenschaften es Ihnen ermöglicht, verschiedene Versionen einer API mit denselben Java-Klassen zu verarbeiten, wodurch Ihr Code wartbarer und anpassungsfähiger an Änderungen wird.

Best Practices und zusätzliche Konfigurationsoptionen

Nachdem Sie verstanden haben, wie man den ObjectMapper so konfiguriert, dass er unbekannte Eigenschaften ignoriert, wollen wir einige Best Practices und zusätzliche Konfigurationsoptionen besprechen, die in realen Anwendungen nützlich sein können.

Best Practices

1. Wählen Sie den richtigen Ansatz für Ihre Anwendung

  • Globale Konfiguration: Verwenden Sie objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false), wenn Sie möchten, dass alle Ihre Deserialisierungsoperationen unbekannte Eigenschaften ignorieren.
  • Annotation auf Klassenebene: Verwenden Sie @JsonIgnoreProperties(ignoreUnknown = true), wenn Sie nur möchten, dass bestimmte Klassen unbekannte Eigenschaften ignorieren.

2. Berücksichtigen Sie Fehlerbehandlung und Protokollierung

Auch beim Ignorieren unbekannter Eigenschaften kann es nützlich sein, zu protokollieren, wenn unbekannte Eigenschaften gefunden werden, insbesondere in Entwicklungs- oder Testumgebungen.

Lassen Sie uns ein Beispiel mit benutzerdefinierter Behandlung für unbekannte Eigenschaften erstellen:

  1. Erstellen Sie eine neue Datei unter ~/project/src/main/java/com/labex/json/LoggingUnknownPropertiesDemo.java
  2. Fügen Sie der Datei den folgenden Code hinzu:
package com.labex.json;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;

import java.io.IOException;

public class LoggingUnknownPropertiesDemo {
    public static void main(String[] args) {
        try {
            // Create a JSON string with an extra property
            String jsonWithExtraProperty =
                "{\"name\":\"John Doe\",\"age\":30,\"email\":\"[email protected]\"}";

            // Create an ObjectMapper instance
            ObjectMapper objectMapper = new ObjectMapper();

            // Configure ObjectMapper to ignore unknown properties
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

            // Add a problem handler to log unknown properties
            objectMapper.addHandler(new DeserializationProblemHandler() {
                @Override
                public boolean handleUnknownProperty(DeserializationContext ctxt,
                                                     JsonParser p,
                                                     com.fasterxml.jackson.databind.JsonDeserializer<?> deserializer,
                                                     Object beanOrClass,
                                                     String propertyName) throws IOException {
                    System.out.println("WARNING: Unknown property '" + propertyName +
                                      "' found during deserialization of " +
                                      beanOrClass.getClass().getSimpleName());
                    // Skip the value and continue
                    p.skipChildren();
                    return true;
                }
            });

            // Deserialize the JSON into a Person object
            Person person = objectMapper.readValue(jsonWithExtraProperty, Person.class);

            System.out.println("Successfully deserialized: " + person);

        } catch (Exception e) {
            System.out.println("Error occurred: " + e.getMessage());
        }
    }
}
  1. Kompilieren und führen Sie diese Klasse aus:
    cd ~/project
    mvn compile exec:java -Dexec.mainClass="com.labex.json.LoggingUnknownPropertiesDemo"

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

WARNING: Unknown property 'email' found during deserialization of Person
Successfully deserialized: Person{name='John Doe', age=30}

Dieser Ansatz ermöglicht es Ihnen, unbekannte Eigenschaften zu ignorieren und gleichzeitig über deren Vorhandensein informiert zu sein, was für Debugging- oder Überwachungszwecke nützlich sein kann.

Zusätzliche Konfigurationsoptionen

Der ObjectMapper von Jackson bietet viele weitere nützliche Konfigurationsoptionen. Hier sind einige, die oft Hand in Hand mit dem Ignorieren unbekannter Eigenschaften gehen:

  1. Erstellen Sie eine neue Datei unter ~/project/src/main/java/com/labex/json/AdditionalConfigurationsDemo.java
  2. Fügen Sie der Datei den folgenden Code hinzu:
package com.labex.json;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

public class AdditionalConfigurationsDemo {
    public static void main(String[] args) {
        try {
            // Create a Person object
            Person person = new Person("John Doe", 30);

            // Create an ObjectMapper with various configurations
            ObjectMapper objectMapper = new ObjectMapper();

            // Ignore unknown properties during deserialization
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

            // Allow JSON with single quotes
            objectMapper.configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);

            // Allow JSON with unquoted field names
            objectMapper.configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);

            // Format output JSON with indentation for better readability
            objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);

            // Serialize the Person object to JSON with pretty printing
            String jsonString = objectMapper.writeValueAsString(person);
            System.out.println("Formatted JSON:");
            System.out.println(jsonString);

            // Parse JSON with single quotes and unquoted field names
            String nonStandardJson = "{'name':'Jane Smith', age:25}";
            Person parsedPerson = objectMapper.readValue(nonStandardJson, Person.class);
            System.out.println("\nParsed from non-standard JSON: " + parsedPerson);

        } catch (Exception e) {
            System.out.println("Error occurred: " + e.getMessage());
        }
    }
}
  1. Kompilieren und führen Sie diese Klasse aus:
    cd ~/project
    mvn compile exec:java -Dexec.mainClass="com.labex.json.AdditionalConfigurationsDemo"

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

Formatted JSON:
{
  "name" : "John Doe",
  "age" : 30
}

Parsed from non-standard JSON: Person{name='Jane Smith', age=25}

Dieses Beispiel demonstriert verschiedene Konfigurationsoptionen:

  • SerializationFeature.INDENT_OUTPUT: Macht das generierte JSON mit Einrückungen lesbarer
  • ALLOW_SINGLE_QUOTES: Erlaubt JSON mit einfachen Anführungszeichen anstelle von doppelten Anführungszeichen
  • ALLOW_UNQUOTED_FIELD_NAMES: Erlaubt Feldnamen ohne Anführungszeichen

Diese zusätzlichen Konfigurationen können in verschiedenen Szenarien nützlich sein, z. B. bei der Arbeit mit nicht standardmäßigem JSON oder wenn Sie Ihre JSON-Ausgabe lesbarer gestalten müssen.

Zusammenfassung

In diesem Lab haben Sie gelernt, wie Sie den ObjectMapper von Jackson so konfigurieren, dass er unbekannte Eigenschaften in JSON-Daten ignoriert. Dies ist eine wichtige Fähigkeit für den Aufbau robuster Java-Anwendungen, die JSON aus externen Quellen verarbeiten.

Sie haben Folgendes gemeistert:

  • Grundlegende JSON-Serialisierung und -Deserialisierung mit dem ObjectMapper von Jackson
  • Das Problem unbekannter Eigenschaften in JSON und warum diese Ausnahmen verursachen können
  • Zwei Ansätze zur Behandlung unbekannter Eigenschaften:
    • Globale Konfiguration mit objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    • Annotation auf Klassenebene mit @JsonIgnoreProperties(ignoreUnknown = true)
  • Praktische Anwendungen und reale Anwendungsfälle:
    • Nutzung von APIs von Drittanbietern, die sich im Laufe der Zeit ändern können
    • Unterstützung mehrerer Versionen einer API mit demselben Code
  • Best Practices und zusätzliche Konfigurationsoptionen:
    • Protokollierung unbekannter Eigenschaften während der Deserialisierung
    • Konfigurieren des ObjectMapper für verschiedene JSON-Formate und Ausgabestile

Diese Fähigkeiten helfen Ihnen beim Aufbau widerstandsfähigerer Java-Anwendungen, die JSON-Daten aus verschiedenen Quellen problemlos verarbeiten können, selbst wenn sich das Datenformat ändert oder unerwartete Eigenschaften enthält.

Für weiteres Lernen sollten Sie andere Jackson-Annotationen und -Funktionen erkunden, die bei komplexeren JSON-Verarbeitungsszenarien helfen können, wie z. B. benutzerdefinierte Serialisierer und Deserialisierer, die Behandlung von Datumsformaten und die polymorphe Typenbehandlung.