在 Spring 中集成 Fastjson2

在 Spring 中集成 Fastjson2

0. 依赖配置

Fastjson2采用多module的结构设计,对SpringFramework等框架的支持现独立在extension包中。

Maven:

<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2-extension-spring5</artifactId>
    <version>2.0.59</version>
</dependency>

or

<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2-extension-spring6</artifactId>
    <version>2.0.59</version>
</dependency>
 

Gradle:

dependencies {
    implementation 'com.alibaba.fastjson2:fastjson2-extension-spring5:2.0.59'
}

or

dependencies {
    implementation 'com.alibaba.fastjson2:fastjson2-extension-spring6:2.0.59'
}
 

2.0.23版本之后为了兼容Spring 5.x / 6.x,将不同版本独立开不同的依赖包。 如使用2.0.23之前的版本,请参考:

Maven:

<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2-extension</artifactId>
    <version>2.0.x</version>
</dependency>
 

Gradle:

dependencies {
    implementation 'com.alibaba.fastjson2:fastjson2-extension:2.0.x'
}
 

1. 参数配置

Fastjson2对于序列化和反序列化的行为进行了重新设计,所以FastJsonConfig也会重新适配。

Packagecom.alibaba.fastjson2.support.config.FastJsonConfig

Attributes:

参数 类型 描述
charset Charset 指定的字符集,默认UTF-8
dateFormat String 指定的日期格式,默认yyyy-MM-dd HH:mm:ss
writerFilters Filter[] 配置序列化过滤器
writerFeatures JSONWriter.Feature[] 配置序列化的指定行为,更多配置请见:Features文档
readerFilters Filter[] 配置反序列化过滤器
readerFeatures JSONReader.Feature[] 配置反序列化的指定行为,更多配置请见:Features文档
jsonb boolean 是否采用JSONB进行序列化和反序列化,默认false
symbolTable JSONB.SymbolTable JSONB序列化和反序列化的符号表,只有使用JSONB时生效

2. 在 Spring Web MVC 中集成 Fastjson2

在Fastjson2中,同样可以使用FastJsonHttpMessageConverter 和 FastJsonJsonView 为 Spring MVC 构建的 Web 应用提供更好的性能体验。

2. 配置FastJsonHttpMessageConverter

@Configuration
public class WebMvcConfigurer extends WebMvcConfigurationSupport {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        config.setDateFormat("yyyy-MM-dd HH:mm:ss");
        config.setCharset(StandardCharsets.UTF_8);
        
        converter.setFastJsonConfig(config);
        // 从2.0.59版本开始,FastJsonHttpMessageConverter默认charset已经是UTF-8,无需手动设置
        // converter.setDefaultCharset(StandardCharsets.UTF_8);
        converters.add(0, converter);
    }
}
 

2.2 Spring Web MVC View

使用 FastJsonJsonView 来设置 Spring MVC 默认的视图模型解析器,以提高 @Controller @ResponseBody ModelAndView JSON序列化速度。

Packagecom.alibaba.fastjson2.support.spring.webservlet.view.FastJsonJsonView

Before Spring 5 Example:

@Configuration
@EnableWebMvc
public class WebMvcConfigurer extends WebMvcConfigurerAdapter {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        FastJsonJsonView fastJsonJsonView = new FastJsonJsonView();
        //自定义配置...
        //FastJsonConfig config = new FastJsonConfig();
        //config.set...
        //fastJsonJsonView.setFastJsonConfig(config);
        registry.enableContentNegotiation(fastJsonJsonView);
    }
}
 

从Spring5.0版本开始,WebMvcConfigurerAdapter 已被弃用,您可以直接实现WebMvcConfigurer接口,而无需使用此适配器。

After Spring 5 Example:

@Configuration
@EnableWebMvc
public class CustomWebMvcConfigurer implements WebMvcConfigurer {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        FastJsonJsonView fastJsonJsonView = new FastJsonJsonView();
        //自定义配置...
        //FastJsonConfig config = new FastJsonConfig();
        //config.set...
        //fastJsonJsonView.setFastJsonConfig(config);
        registry.enableContentNegotiation(fastJsonJsonView);
    }

}
 

参考:Spring Framework 官方文档 Spring Web MVC 部分,查看更多 。

3. 在 Spring Webflux 中集成 Fastjson2

Fastjson2提供了针对Spring响应式编解码的支持,可以使用Fastjson2DecoderFastjson2Encoder来替换Spring默认的DecoderEncoder

Packages:

  • com.alibaba.fastjson2.support.spring.codec.Fastjson2Decoder
  • com.alibaba.fastjson2.support.spring.codec.Fastjson2Encoder

Spring6 Packages:

  • com.alibaba.fastjson2.support.spring6.codec.Fastjson2Decoder
  • com.alibaba.fastjson2.support.spring6.codec.Fastjson2Encoder

Example1:

@Configuration
public class CustomWebfluxConfigure implements WebFluxConfigurer {

    @Override
    public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
        //configurer.registerDefaults(false);
        CodecConfigurer.CustomCodecs customCodecs = configurer.customCodecs();
        //自定义配置
        FastJsonConfig config = new FastJsonConfig();
        config.setCharset(StandardCharsets.UTF_8);
        config.setDateFormat("yyyy-MM-dd HH:mm:ss");
        //设置支持的媒体类型
        MimeType[] supportedMimeTypes = new MimeType[]{MediaType.APPLICATION_JSON};
        //注册解码器
        customCodecs.register(new Fastjson2Decoder(config,supportedMimeTypes));
        //注册编码器
        customCodecs.register(new Fastjson2Encoder(config,supportedMimeTypes));
    }
}
 

Example2:

@Bean
public CodecCustomizer codecCustomizer() {
    return configurer -> {
        //configurer.registerDefaults(false);
        CodecConfigurer.CustomCodecs customCodecs = configurer.customCodecs();
        //自定义配置
        FastJsonConfig config = new FastJsonConfig();
        config.setCharset(StandardCharsets.UTF_8);
        config.setDateFormat("yyyy-MM-dd HH:mm:ss");
        //设置支持的媒体类型
        MimeType[] supportedMimeTypes = new MimeType[]{MediaType.APPLICATION_JSON};
        //注册解码器
        customCodecs.register(new Fastjson2Decoder(config, supportedMimeTypes));
        //注册编码器
        customCodecs.register(new Fastjson2Encoder(config, supportedMimeTypes));
    };
}
 

4. 在 Spring Web Socket 中集成 Fastjson2

在Fastjson2中,同样也对 Spring WebSocket 给予支持,可以使用 FastjsonSockJsMessageCodec 进行配置。

Packagecom.alibaba.fastjson2.support.spring.websocket.sockjs.FastjsonSockJsMessageCodec

Example:

@Component
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {

    @Resource
    WebSocketHandler handler;

    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        //自定义配置...
        //FastjsonSockJsMessageCodec messageCodec = new FastjsonSockJsMessageCodec();
        //FastJsonConfig config = new FastJsonConfig();
        //config.set...
        //messageCodec.setFastJsonConfig(config);
        registry.addHandler(handler, "/sockjs").withSockJS().setMessageCodec(new FastjsonSockJsMessageCodec());
    }

}
 

参考:Spring Framework 官方文档 Spring Web Socket 部分,查看更多 。

5. 在 Spring Data Redis 中集成 Fastjson2

在Fastjson2中,同样可以使用 GenericFastJsonRedisSerializer 或 FastJsonRedisSerializer 为 Spring Data Redis 提供更好的性能体验。

5.1 Generic Redis Serializer

使用 GenericFastJsonRedisSerializer 作为 RedisTemplate 的 RedisSerializer 来提升JSON序列化和反序列化速度。

Packagecom.alibaba.fastjson2.support.spring.data.redis.GenericFastJsonRedisSerializer

Example:

@Configuration
public class RedisConfiguration {

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        GenericFastJsonRedisSerializer fastJsonRedisSerializer = new GenericFastJsonRedisSerializer();
        redisTemplate.setDefaultSerializer(fastJsonRedisSerializer);//设置默认的Serialize,包含 keySerializer & valueSerializer

        //redisTemplate.setKeySerializer(fastJsonRedisSerializer);//单独设置keySerializer
        //redisTemplate.setValueSerializer(fastJsonRedisSerializer);//单独设置valueSerializer
        return redisTemplate;
    }
}
 

5.2 Customized Redis Serializer

通常使用 GenericFastJsonRedisSerializer 即可满足大部分场景,如果你想定义特定类型专用的 RedisTemplate 可以使用 FastJsonRedisSerializer 来代替 GenericFastJsonRedisSerializer ,配置是类似的。

Packagecom.alibaba.fastjson2.support.spring.data.redis.FastJsonRedisSerializer

Example:

@Configuration
public class RedisConfiguration {

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(User.class);
        redisTemplate.setDefaultSerializer(fastJsonRedisSerializer);
        return redisTemplate;
    }
}
 

5.3 JSONB Redis Serializer

如果你准备使用 JSONB 作为对象序列/反序列化的方式并对序列化速度有较高的要求的话,可以对jsonb参数进行配置,该参数是 fastjson 2.0.6 版本中新增的支持,配置也很简单。

Example:

@Configuration
public class RedisConfiguration {

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // GenericFastJsonRedisSerializer use jsonb
        // GenericFastJsonRedisSerializer fastJsonRedisSerializer = new GenericFastJsonRedisSerializer(true);

        // FastJsonRedisSerializer use jsonb
        FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(User.class);
        // FastJsonConfig fastJsonConfig = new FastJsonConfig();
        // fastJsonConfig.setJSONB(true);
        // fastJsonRedisSerializer.setFastJsonConfig(fastJsonConfig);
        redisTemplate.setDefaultSerializer(fastJsonRedisSerializer);

        return redisTemplate;
    }
}
 

参考:Spring Data Redis 官方文档,查看更多 。

6. 在 Spring Messaging 中集成 Fastjson2

在Fastjson2中,同样可以使用 MappingFastJsonMessageConverter 为 Spring Messaging 提供更好的性能体验。

6.1 JSON Message Converter

使用 MappingFastJsonMessageConverter 作为 Spring Cloud Stream 或 Spring Messaging 来提升Message的序列化和反序列化速度。

Packagecom.alibaba.fastjson2.support.spring.messaging.converter.MappingFastJsonMessageConverter

Example:

@Configuration
public class StreamConfiguration {

    @Bean
    @StreamMessageConverter
    public MappingFastJsonMessageConverter messageConverter() {
        return new MappingFastJsonMessageConverter();
    }
}
 

6.2 JSONB Message Converter

如果你准备使用 JSONB 作为对象序列/反序列化的方式并对序列化速度有较高的要求的话,可以对 FastJsonConfig 的 jsonb 参数进行配置,该参数是 fastjson 2.0.6 版本中新增的支持,配置也很简单。

注意:JSONB仅支持将Message的payload序列化为byte[]

Example:

@Configuration
public class StreamConfiguration {

    @Bean
    @StreamMessageConverter
    public MappingFastJsonMessageConverter messageConverter() {
        MappingFastJsonMessageConverter messageConverter = new MappingFastJsonMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setJSONB(true); // use jsonb
        messageConverter.setFastJsonConfig(fastJsonConfig);
        return messageConverter;
    }
}
 

参考:Spring Messaging 官方文档,查看更多 。

 

fastjson2/docs/spring_support_cn.md at main · alibaba/fastjson2

通过特征配置序列化和反序列化的行为

1. 功能介绍

在fastjson 2.x中,有两个Feature,分别用于配置序列化和反序列化的行为。

  • JSONWriter.Feature 配置序列化的行为
  • JSONReader.Feature 配置反序列化的行为

2.在JSON的toJSONString和parse方法中使用特性

2.1 在JSON的toJSONString方法中使用JSONWriter.Feature

Bean bean = ...;
String json = JSON.toJSONString(bean, JSONWriter.Feature.WriteNulls); // 输出对象中值为null的字段
 

2.2 在JSON的parse方法中使用JSONReader.Feature

String jsonStr = ...;
Bean bean = JSON.parseObject(jsonStr, Bean.class, JSONReader.Feature.UseBigDecimalForDoubles); // 将小数数值读取为BigDecimal
 

3.在JSONField和JSONType上配置features

class Model {
    @JSONField(serializeFeatures = JSONWriter.Feature.BrowserCompatible)
    public long value;
}
 

也可以在类别级别使用JSONType注解:

@JSONType(serializeFeatures = JSONWriter.Feature.WriteMapNullValue)
public class Model {
    public String name;
    public int age;
}
 

4. JSONReader.功能介绍

JSONReader.功能 介绍
基于字段 基于字段的反序列化,如果不配置,会默认基于public的字段和getter方法序列化。配置后,会基于非静态的字段(包括private)做反序列化。在fieldbase配置下会更安全
IgnoreNoneSerializable 反序列化忽略非Serialized类型的字段
支持ArrayToBean 支持映射映射到Bean的方式
初始化字符串字段为空 初始化String字段为空字符串""
支持自动输入 支持自动类型,要读取带“@type”类型信息的JSON数据,需要显式打开SupportAutoType
支持SmartMatch 默认下是camel case精确匹配,打开这个后,能够智能识别camel/upper/pascal/snake/Kebab五种case
使用本机对象 默认是使用JSONObject和JSONArray,配置后会使用LinkedHashMap和ArrayList
名称支持类 支持类型为Class的字段,使用Class.forName。为了安全这个是默认关闭的
忽略设置空值 忽略输入为null的字段
尽可能使用默认构造函数 小心使用递归构造函数,在fieldBase打开这个选项没打开的时候,会可能用Unsafe.allocateInstance来实现
使用大数用于浮点数 默认配置会使用BigDecimal来解析小数,打开后会使用Float
使用大数用于双精度数 默认配置会使用BigDecimal来解析小数,打开后会使用Double
枚举不匹配时出错 默认Enum的名称不匹配时会忽略,打开后不匹配会抛出异常
修剪字符串 对读取到的字符串值进行trim处理
不支持自动类型时出错 遇到AutoType报错(涉及是忽略)
重复键值数组 重复的键的值不是替换而是组合成阵列
允许不带引号的字段名称 支持不带双引号的字段名
非字符串键作为字符串 String非类型的Key当做String处理
Base64字符串作为字节数组 将Base64格式的字符串反序列化为byte[]
禁用单引号 允许在 key 和 value 中使用单引号

5. JSONWriter.功能介绍

JSONWriter.功能 介绍
基于字段 基于序列化,如果不配置,会默认基于public的字段和getter方法序列化。配置后,会基于非静态的字段(包括private)做序列化。
IgnoreNoneSerializable 序列化忽略非Serialized类型的字段
Bean 到数组 将对象序列为[101,"XX"]这样的缓存格式,这样的格式会更小
写入空值 序列化输出空值字段
浏览器兼容 在大范围超过JavaScript支持的整数,输出为字符串格式
空值 将null值输出为预测值,整数类型的Number输出为0,小数类型的Number输出为0.0,String类型输出为"",字符类型输出为\u0000,吞吐量和Collection类型输出为[],其余类型输出{}。
将布尔值写入数字 将真输出为1,假输出为0
将非字符串值写入字符串 将非String类型的值输出为String,不包括对象和数据类型
写入类名 序列化时输出类型信息
未写入根类名 同时打开WriteClassName的,不输出根对象的类型信息
NotWriteHashMapArrayListClassName 同时打开WriteClassName,不输出类型为HashMap/ArrayList类型对象的类型信息,反序列结合UseNativeObject使用,能节省序列化结果的大小
未写入默认值 当字段的决定值时,不输出,这样可以节省序列化后结果的大小
使用名称写入枚举 序列化enumusename
使用字符串写入枚举 序列化enum使用toString方法
IgnoreErrorGetter 忽略getter方法的错误
PrettyFormat 技术输出
参考检测 打开引用检测,这个问题是关闭的,和 fastjson 1.x 不一致
将名称写入符号 将字段名按照符号输出,这个仅在JSONB下作业
将 BigDecimal 写为纯文本 序列化BigDecimal使用toPlainString,避免科学计数法
使用单引号 使用单引号
MapSortField 对Map中的KeyValue按照Key做排序后再输出。在某些验签的场景需要使用这个功能
将空列表写为空 将List类型字段的空值序列化输出为空负载"[]"
将空字符串写入为空 将String类型字段的空值序列化输出为空字符串""
将空值写为零 将Number类型字段的空值序列化输出为0
将NullBoolean写入False 将Boolean类型字段的空值序列化输出为false
不写入空数组 数据库类型字段当长度为0时不输出
将非字符串键写入字符串 将Map中的非String类型的Key当做String类型输出
ErrorOnNoneSerializable 序列化非Serialized对象报错
写入PairAsJavaBean 将 Apache Commons 包中的Pair对象当做JavaBean序列化
浏览器安全 浏览器安全,将'<' '>' '(' ')'字符做转义输出
写入长字符串 将长序列化为String
使用序数写入枚举 序列化Enum使用Ordinal,重点是name
写入可抛出类名 序列化Throwable时带上类型信息
大对象 是一个保护措施,是为了防止这个序列化有循环引用对象消耗过多资源的保护措施。
取消引用字段名称 不带引号输出Key
未写入设置类名 当打开WriteClassName时又不想输出Set的类型信息,使用这个Feature
不写数字类名 当打开WriteClassName时又不想输出Number的类型信息,比如L/S/B/F/D这类后缀,使用这个Feature

6. 使用示例

6.1 序列分析示例

// 基本使用
User user = new User(\"张三\", 25, null);
String json = JSON.toJSONString(user, JSONWriter.Feature.WriteNulls);

// 多个Feature组合使用
String json2 = JSON.toJSONString(user, 
    JSONWriter.Feature.WriteNulls, 
    JSONWriter.Feature.PrettyFormat);

// 使用BeanToArray特性
String json3 = JSON.toJSONString(user, JSONWriter.Feature.BeanToArray);
 

6.2 反序列化示例

// 基本使用
String json = \"{\\\"name\\\":\\\"张三\\\",\\\"age\\\":25}\";
User user = JSON.parseObject(json, User.class, JSONReader.Feature.SupportSmartMatch);

// 多个Feature组合使用
User user2 = JSON.parseObject(json, User.class, 
    JSONReader.Feature.SupportSmartMatch, 
    JSONReader.Feature.InitStringFieldAsEmpty);
 

7. 最佳实践建议

  1. 安全性考虑

    • 默认情况下不要开启SupportAutoType,除非确实需要处理带类型信息的JSON
    • 对于不受信任的数据源,珍珠使用FieldBased特性
  2. 性能优化

    • 对于大数据量的序列化,可以考虑使用BeanToArray特性来减小JSON体积
    • 在需要保持字段顺序的场景下,使用MapSortField特性
  3. 兼容性处理

    • 在Web介绍场景中,使用BrowserCompatible来处理大整数
    • 对于需要严格数据格式的场景,开启ErrorOnEnumNotMatch及时发现枚举不匹配问题
  4. 空值处理

    • 根据业务需求选择合适的空值处理策略,如WriteNullsWriteNullStringAsEmpty

 

posted @ 2025-09-30 14:14  CharyGao  阅读(43)  评论(0)    收藏  举报