FASTJSON 2 is a complete rewrite of the original FASTJSON library, designed for the next decade. Key differences:
- New package:
com.alibaba.fastjson2(v1 wascom.alibaba.fastjson) - Better performance: Significant improvements across all operations
- More secure: AutoType disabled by default, no hardcoded whitelist
- Modern Java: JDK 11/17/21 optimizations, Record support, Vector API
- Binary format: Native JSONB support
- JSON Schema: Built-in validation
Yes. Because they use different package names (com.alibaba.fastjson2 vs com.alibaba.fastjson), both can exist in the same project. However, using the compatibility module (com.alibaba:fastjson:2.x) will conflict with FASTJSON 1.x since they share the same package.
- Core library: Java 8+
- Full feature set: Java 11+ (compact string optimizations)
- Vector API optimizations: Java 17+
- Android: Android 8+ (API level 26+)
Yes. FASTJSON 2 is compatible with GraalVM Native Image. Note that ASM-based code generation is not available in native images, so the reflection-based or lambda-based creator will be used instead.
// Parse as JSONObject (for JSON objects)
JSONObject obj = JSON.parseObject(jsonString);
// Parse as JSONArray (for JSON arrays)
JSONArray arr = JSON.parseArray(jsonString);
// Parse as generic Object (auto-detect)
Object result = JSON.parse(jsonString);Use TypeReference for complex generic types:
// List<User>
List<User> users = JSON.parseObject(json, new TypeReference<List<User>>(){});
// Map<String, List<User>>
Map<String, List<User>> map = JSON.parseObject(json,
new TypeReference<Map<String, List<User>>>(){});Use @JSONField(format = "...") or global configuration:
// Per-field
public class Event {
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
public Date eventTime;
}
// Global
JSON.configReaderDateFormat("yyyy-MM-dd");
// Per-call
User user = JSON.parseObject(json, User.class, "yyyy-MM-dd");Enable SupportSmartMatch to automatically handle camelCase, PascalCase, snake_case, and kebab-case:
User user = JSON.parseObject(json, User.class, JSONReader.Feature.SupportSmartMatch);Note: Smart matching is off by default in FASTJSON 2 (it was on by default in v1).
JSONObject obj = JSON.parseObject(json,
JSONReader.Feature.UseBigDecimalForFloats,
JSONReader.Feature.UseBigDecimalForDoubles);User user = JSON.parseObject(json, User.class, JSONReader.Feature.TrimString);String json = JSON.toJSONString(user, JSONWriter.Feature.WriteNulls);For specific null handling strategies:
// null String → ""
JSONWriter.Feature.WriteNullStringAsEmpty
// null List → []
JSONWriter.Feature.WriteNullListAsEmpty
// null Number → 0
JSONWriter.Feature.WriteNullNumberAsZero
// null Boolean → false
JSONWriter.Feature.WriteNullBooleanAsFalseString json = JSON.toJSONString(user, JSONWriter.Feature.PrettyFormat);JavaScript cannot handle Java long values beyond Number.MAX_SAFE_INTEGER (2^53 - 1). Use BrowserCompatible or WriteLongAsString:
// Auto-detect and convert large numbers to strings
String json = JSON.toJSONString(user, JSONWriter.Feature.BrowserCompatible);
// Always serialize Long as String
String json = JSON.toJSONString(user, JSONWriter.Feature.WriteLongAsString);Use @JSONField(ordinal = N) or @JSONType(orders = {...}):
public class User {
@JSONField(ordinal = 1)
public String name;
@JSONField(ordinal = 2)
public int age;
}
// or at class level
@JSONType(orders = {"name", "age", "email"})
public class User { ... }Multiple approaches:
// Annotation-based
@JSONField(serialize = false)
public String password;
// Class-level ignore
@JSONType(ignores = {"password", "secretKey"})
public class User { ... }
// Filter-based
PropertyFilter filter = (object, name, value) -> !"password".equals(name);
String json = JSON.toJSONString(user, filter);Yes. Unlike FASTJSON 1.x, FASTJSON 2 disables AutoType by default. JSON data containing @type fields will be ignored unless you explicitly enable AutoType.
Use AutoTypeFilter with a narrow whitelist instead of enabling global AutoType:
// Preferred: scoped filter with narrow whitelist
Filter autoTypeFilter = JSONReader.autoTypeFilter(
"com.mycompany.model" // Only allow classes in this package
);
Object result = JSON.parseObject(json, Object.class, autoTypeFilter);If you must enable global AutoType (not recommended for internet-facing services):
Object result = JSON.parseObject(json, Object.class, JSONReader.Feature.SupportAutoType);SafeMode completely disables AutoType, even if explicitly configured in the code. Enable it with a JVM parameter:
-Dfastjson2.parser.safeMode=true
- Use byte[] input when possible -
JSON.parseObject(bytes, Type.class)avoids String conversion overhead. - Reuse JSONPath instances -
JSONPath.of("$.id")is cacheable and thread-safe. - Use partial parsing - For large documents, use JSONPath to extract only what you need.
- Use JSONB - For internal service communication, JSONB is significantly faster than text JSON.
- Avoid unnecessary features - Each enabled feature adds a small overhead.
- Use byte[] output -
JSON.toJSONBytes(obj)is faster thanJSON.toJSONString(obj)for most use cases. - Use BeanToArray -
JSONWriter.Feature.BeanToArrayproduces smaller output and is faster to serialize. - Use JSONB - For binary protocols, JSONB is significantly faster.
FASTJSON 2 consistently outperforms Jackson and Gson in benchmarks. See the detailed benchmark data at fastjson_benchmark.
Add the extension dependency and configure the message converter. See the full Spring Integration Guide.
Quick setup for Spring 6.x:
@Configuration
public class JsonConfig extends WebMvcConfigurationSupport {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
converters.add(0, converter);
}
}Use GenericFastJsonRedisSerializer:
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setDefaultSerializer(new GenericFastJsonRedisSerializer());
return template;
}Use the compatibility package as a drop-in replacement:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.61</version>
</dependency>This provides the same package name (com.alibaba.fastjson) with FASTJSON 2's engine underneath.
In FASTJSON 2, use ObjectReaderProvider:
JSONFactory.getDefaultObjectReaderProvider().addAutoTypeAccept("com.mycompany.xxx");| Fastjson 1.x | Fastjson 2.x |
|---|---|
ObjectSerializer |
ObjectWriter |
ObjectDeserializer |
ObjectReader |
SerializerFeature |
JSONWriter.Feature |
Feature (parser) |
JSONReader.Feature |
See the full Migration Guide for the complete API mapping table.
Common causes:
- Malformed JSON - Validate your JSON with a linter.
- Type mismatch - The JSON structure doesn't match the target Java type.
- Missing default constructor - The target class needs a no-arg constructor (or use
@JSONCreator). - Enum mismatch - Enable
ErrorOnEnumNotMatchto get detailed error messages.
Check for:
- Fields must be
publicor have public getter methods (unless usingFieldBasedfeature). transientfields are skipped by default.- Check if
@JSONField(serialize = false)or@JSONType(ignores = ...)is applied.
Check for:
- JSON key names must match Java field names (or use
@JSONField(name = "...")to map). - Enable
SupportSmartMatchif the JSON uses a different naming convention. - Fields must be
publicor have public setter methods (unless usingFieldBasedfeature).
FASTJSON 2 disables AutoType by default. If your JSON contains @type fields:
- Use
AutoTypeFilterwith a narrow whitelist for specific classes. - Or enable
SupportAutoType(not recommended for untrusted input). - Do not use AutoType in internet-facing services.