fastjson2/docs/autotype_cn.md

74 lines
2.9 KiB
Markdown
Raw Normal View History

2022-05-21 17:17:26 +08:00
# FASTJSON 2 Autotype机制介绍
## 1. AutoType功能介绍
FASTJSON支持AutoType功能这个功能在序列化的JSON字符串中带上类型信息在反序列化时不需要传入类型实现自动类型识别。
## 2. AutoType安全机制介绍
2022-06-05 00:28:55 +08:00
* 必须显示打开才能使用。和fastjson 1.x不一样fastjson 1.x为了兼容有一个白名单在fastjson 2中没有任何白名单也不包括任何Exception类的白名单必须显示打开才能使用。这可以保证缺省配置下是安全的。
2022-05-21 17:17:26 +08:00
* 支持配置safeMode在safeMode打开后显式传入AutoType参数也不起作用
* 显式打开后会经过内置黑名单过滤。该黑名单能拦截大部分常见风险这个机制不能保证绝对安全打开AutoType不应该在暴露在公网的场景下使用。
## 3. AutoType功能使用介绍
### 3.1 序列化带上类型信息
序列化是带上类型信息需要使用JSONWriter.Feature.WriteClassName。比如
```java
Bean bean = ...;
String jsonString = JSON.toJSONString(bean, JSONWriter.Feature.WriteClassName);
```
很多时候root对象是可以知道类型的里面的对象字段是基类或者不确定类型这个时候不输出root对象的类型信息可以减少序列化结果的大小也能提升反序列化的性能。
```java
Bean bean = ...;
String jsonString = JSON.toJSONString(bean, JSONWriter.Feature.WriteClassName, JSONWriter.Feature.NotWriteRootClassName);
```
### 3.2 反序列化打开AutoType功能支持自动类型
```java
2022-05-21 20:52:56 +08:00
Bean bean = (Bean) JSON.parseObject(jsonString, Object.class, JSONReader.Feature.SupportAutoType);
2022-05-21 17:17:26 +08:00
```
## 4. 配置safeMode
2022-06-10 17:55:56 +08:00
配置SafeMode是完全禁用autotype功能如果程序中显示指定也不行
2022-05-21 17:17:26 +08:00
### 4.1 JVM启动参数配置
```
-Dfastjson2.parser.safeMode=true
```
2022-06-10 17:55:56 +08:00
## 5. 使用AutoTypeFilter在不打开AutoTypeSupport时实现自动类型
2022-06-10 17:58:32 +08:00
当打开AutoTypeSupport虽然内置了一个比较广泛的黑名单但仍然是不够安全的。下面有一种办法是控制当前调用的AutoType支持范围避免全局打开这个更安全。
2022-06-10 17:55:56 +08:00
```java
public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
static final Filter autoTypeFilter = JSONReader.autoTypeFilter(
// 按需加上需要支持自动类型的类名前缀,范围越小越安全
"org.springframework.security.core.authority.SimpleGrantedAuthority"
);
private Class<T> clazz;
public FastJsonRedisSerializer(Class<T> clazz) {
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) {
if (t == null) {
return new byte[0];
}
return JSON.toJSONBytes(t, JSONWriter.Feature.WriteClassName);
}
@Override
public T deserialize(byte[] bytes) {
if (bytes == null || bytes.length <= 0) {
return null;
}
return JSON.parseObject(bytes, clazz, autoTypeFilter);
}
}
```