Fast JSON Parsing in Java with New Security Rules in Fastjson2

If you've been working with Java for more than five years, the name Fastjson probably evokes mixed feelings in you. On one hand, the library was indeed faster than Jackson. On the other hand, regular deserialization vulnerabilities through AutoType turned its use into a constant headache for security specialists.
The Alibaba team knew these problems better than anyone. Two years ago, they essentially rewrote the library from scratch. Meet Fastjson2: a reimagined engine for working with JSON, where security and performance on modern Java versions were taken as the foundation.
How Security Has Changed
The main sin of the first version was the AutoType mechanism. It could create arbitrary Java objects from JSON payload directly during parsing. Attackers regularly found ways to bypass the built-in blocked classes list and trigger RCE.
In Fastjson2, the approach changed dramatically. AutoType is now disabled by default, and class scanning works without hardcoded whitelists. A SafeMode was introduced, which completely prohibits automatic assembly of arbitrary objects.
All configuration flags are now set to OFF by default. The library no longer tries to guess types where doing so could cause harm.
Core Features
The developers targeted modern JDK versions, ranging from Java 8 to Java 21. The engine is optimized for Vector API usage, Record types, and compact strings.
Here's what stands out when getting acquainted with the library:
- Dual format support. Both regular text JSON and the binary JSONB protocol.
- Fast selective parsing via JSONPath without creating intermediate Java objects.
- Extension modules for Kotlin with a convenient DSL and full Spring Framework support for versions 5 and 6.
- Native compilation with GraalVM Native Image out of the box.
Quick Start in Code
Adding the library involves including a single dependency in pom.xml:
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.61</version>
</dependency>
A simple example of parsing and serialization looks familiar:
import com.alibaba.fastjson2.JSON;
// Парсинг строки в объект
User user = JSON.parseObject("{\"name\":\"John\",\"age\":25}", User.class);
// Сериализация объекта в JSON
String json = JSON.toJSONString(user);
If you write in Kotlin, the fastjson2-kotlin module offers concise extensions. The code turns out noticeably cleaner thanks to the to<T>() extension function:
import com.alibaba.fastjson2.*
val text = """{"id":1,"name":"John"}"""
val user = text.to<User>()
val jsonBytes = user.toJSONByteArray()
Binary JSONB Format for Microservices
Text JSON remains the standard for REST APIs, but in inter-service communication it loses ground due to excessive size and string conversion overhead. Fastjson2 contains a built-in implementation of the binary JSONB format.
JSONB encodes data types and structure into a compact byte set. This provides substantial traffic savings and speeds up RPC services.
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);
Compression with the BeanToArray option transforms an object into a value array without repeating field names, bringing the format's efficiency closer to Protobuf or Kryo.
Selective Reading via JSONPath
Often, from a huge JSON response of a microservice, you only need to extract one or two fields. Classic parsers like Jackson first build a complete tree in memory or create an object with all fields, consuming CPU and memory resources.
Fastjson2 solves this problem with an implementation of the SQL:2016 standard JSONPath. It can extract data directly from a raw byte stream:
byte[] payload = fetchLargeJsonFromNetwork();
// Создаём и кэшируем путь
JSONPath path = JSONPath.of("$.data.user.id");
// Извлекаем значение напрямую из байтового массива
JSONReader reader = JSONReader.of(payload);
Object userId = path.extract(reader);
This trick is useful in high-load data processing pipelines where unnecessary object allocations in the JVM immediately lead to frequent Garbage Collector pauses.
Migrating from the First Version
Achieving full backward compatibility when changing major versions is impossible, but the authors tried to ease the transition. A compatibility module was created for projects relying on the old API:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.61</version>
</dependency>
It uses the old groupId and com.alibaba.fastjson packages, but internally runs on the new v2 engine. This makes it possible to update without rewriting hundreds of imports in legacy code.
However, when migrating, you need to account for important changes:
- Cyclic reference parsing is disabled by default.
- Smart Match field matching no longer works out of the box.
- All serializer options must be explicitly enabled through
JSONWriter.Feature.
Fastjson2 turned out to be a mature and solid product. The developers learned from past mistakes, eliminated dangerous default settings, and gave the Java ecosystem a truly fast tool.
Definitely give Fastjson2 a try if you're developing high-load services, working with Spring 6 / GraalVM Native Image, or looking for an alternative to heavy serialization formats in Kotlin projects.
Related projects