Schnelles JSON-Parsing in Java mit neuen Sicherheitsregeln in Fastjson2

Wenn Sie seit mehr als fünf Jahren mit Java arbeiten, weckt der Name Fastjson wahrscheinlich gemischte Gefühle. Einerseits war die Bibliothek tatsächlich schneller als Jackson. Andererseits wurden regelmäßige Deserialisierungs-Schwachstellen durch AutoType zu einer ständigen Belastung für Sicherheitsspezialisten.
Das Alibaba-Team kannte diese Probleme besser als jeder andere. Vor zwei Jahren haben sie die Bibliothek im Wesentlichen von Grund auf neu geschrieben. Lernen Sie Fastjson2 kennen: eine neu konzipierte Engine für die Arbeit mit JSON, bei der Sicherheit und Leistung auf modernen Java-Versionen als Grundlage dienen.
Wie sich die Sicherheit verändert hat
Die Hauptsünde der ersten Version war der AutoType-Mechanismus. Er konnte beliebige Java-Objekte direkt während des Parsings aus dem JSON-Payload erstellen. Angreifer fanden regelmäßig Möglichkeiten, die eingebaute Liste blockierter Klassen zu umgehen und RCE auszulösen.
In Fastjson2 hat sich der Ansatz dramatisch verändert. AutoType ist jetzt standardmäßig deaktiviert, und die Klassensuche funktioniert ohne hartcodierte Whitelists. Ein SafeMode wurde eingeführt, der die automatische Zusammenstellung beliebiger Objekte vollständig untersagt.
Alle Konfigurationsflags sind jetzt standardmäßig auf OFF gesetzt. Die Bibliothek versucht nicht mehr, Typen zu erraten, wo dies Schaden anrichten könnte.
Kernfunktionen
Die Entwickler zielten auf moderne JDK-Versionen, von Java 8 bis Java 21. Die Engine ist für die Nutzung der Vector API, Record-Typen und kompakte Strings optimiert.
Das sticht bei der Bekanntschaft mit der Bibliothek besonders hervor:
- Duales Format-Support. Sowohl normales Text-JSON als auch das binäre JSONB-Protokoll.
- Schnelles selektives Parsing über JSONPath ohne Erstellung intermediärer Java-Objekte.
- Erweiterungsmodule für Kotlin mit einer praktischen DSL und vollständiger Spring Framework-Support für Versionen 5 und 6.
- Native Kompilierung mit GraalVM Native Image out of the box.
Schneller Einstieg im Code
Das Hinzufügen der Bibliothek umfasst das Einbinden einer einzelnen Abhängigkeit in pom.xml:
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.61</version>
</dependency>
Ein einfaches Beispiel für Parsing und Serialisierung sieht vertraut aus:
import com.alibaba.fastjson2.JSON;
// Парсинг строки в объект
User user = JSON.parseObject("{\"name\":\"John\",\"age\":25}", User.class);
// Сериализация объекта в JSON
String json = JSON.toJSONString(user);
Wenn Sie in Kotlin schreiben, bietet das fastjson2-kotlin-Modul prägnante Erweiterungen. Der Code wird dank der to<T>()-Erweiterungsfunktion spürbar sauberer:
import com.alibaba.fastjson2.*
val text = """{"id":1,"name":"John"}"""
val user = text.to<User>()
val jsonBytes = user.toJSONByteArray()
Binäres JSONB-Format für Microservices
Text-JSON bleibt der Standard für REST-APIs, verliert aber bei der dienstübergreifenden Kommunikation an Boden wegen übermäßiger Größe und String-Konvertierungs-Overhead. Fastjson2 enthält eine eingebaute Implementierung des binären JSONB-Formats.
JSONB kodiert Datentypen und Struktur in einen kompakten Byte-Satz. Dies bietet erhebliche Traffic-Einsparungen und beschleunigt RPC-Dienste.
User user = new User(1, "John");
// Сериализация в байтовый массив JSONB
byte[] bytes = JSONB.toBytes(user);
// Сериализация с дополнительным сжатием структурированных данных
byte[] compactBytes = JSONB.toBytes(user, JSONWriter.Feature.BeanToArray);
// Обратный парсинг
User parsedUser = JSONB.parseObject(bytes, User.class);
Komprimierung mit der BeanToArray-Option transformiert ein Objekt in ein Wert-Array ohne Wiederholung von Feldnamen und bringt die Effizienz des Formats näher an Protobuf oder Kryo.
Selektives Lesen über JSONPath
Oft brauchen Sie aus einer riesigen JSON-Antwort eines Microservices nur ein oder zwei Felder. Klassische Parser wie Jackson erstellen zuerst einen vollständigen Baum im Speicher oder ein Objekt mit allen Feldern und verbrauchen CPU- und Speicherressourcen.
Fastjson2 löst dieses Problem mit einer Implementierung des SQL:2016-Standards JSONPath. Es kann Daten direkt aus einem roten Byte-Stream extrahieren:
byte[] payload = fetchLargeJsonFromNetwork();
// Создаём и кэшируем путь
JSONPath path = JSONPath.of("$.data.user.id");
// Извлекаем значение напрямую из байтового массива
JSONReader reader = JSONReader.of(payload);
Object userId = path.extract(reader);
Dieser Trick ist nützlich in Hochlast-Datenverarbeitungspipelines, wo unnötige Objektallokationen in der JVM sofort zu häufigen Garbage-Collector-Pausen führen.
Migration von der ersten Version
Eine vollständige Abwärtskompatibilität bei Versionswechseln zu erreichen ist unmöglich, aber die Autoren versuchten, den Übergang zu erleichtern. Ein Kompatibilitätsmodul wurde für Projekte erstellt, die auf der alten API basieren:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.61</version>
</dependency>
Es verwendet die alten groupId- und com.alibaba.fastjson-Pakete, läuft aber intern auf der neuen v2-Engine. Dies macht es möglich, zu aktualisieren, ohne Hunderte von Imports in Legacy-Code umzuschreiben.
Bei der Migration müssen jedoch wichtige Änderungen berücksichtigt werden:
- Zyklische Referenz-Parsing ist standardmäßig deaktiviert.
- Smart Match-Feldabgleich funktioniert nicht mehr out of the box.
- Alle Serializer-Optionen müssen explizit über
JSONWriter.Featureaktiviert werden.
Fastjson2 entpuppte sich als ausgereiftes und solides Produkt. Die Entwickler haben aus vergangenen Fehlern gelernt, gefährliche Standardeinstellungen eliminiert und dem Java-Ökosystem ein wirklich schnelles Werkzeug gegeben.
Probieren Sie Fastjson2 definitiv aus, wenn Sie hochlastfähige Dienste entwickeln, mit Spring 6 / GraalVM Native Image arbeiten oder eine Alternative zu schweren Serialisierungsformaten in Kotlin-Projekten suchen.
Ähnliche Projekte