配置SpringMvc全局序列化与反序列化,解决Long类型下精度丢失问题(使用FastJson2)

注意:方式一与方式二不可共同设置

方式一、使用Jackson解决Long类型在反序列化过程中精度丢失

SpringBoot添加配置文件

@Configuration
public class JacksonConfig {

@Bean
public Jackson2ObjectMapperBuilderCustomizer customizer() {
return builder -> {
// 全局配置序列化返回 JSON 处理
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE);
javaTimeModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE);
javaTimeModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE);
javaTimeModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
builder.modules(javaTimeModule);
builder.timeZone(TimeZone.getDefault());
};
}

@JacksonStdImpl
static class BigNumberSerializer extends NumberSerializer {

/**
* 根据 JS Number.MAX_SAFE_INTEGER 与 Number.MIN_SAFE_INTEGER 得来
*/
private static final long MAX_SAFE_INTEGER = 9007199254740991L;
private static final long MIN_SAFE_INTEGER = -9007199254740991L;

/**
* 提供实例
*/
public static final BigNumberSerializer INSTANCE = new BigNumberSerializer(Number.class);

public BigNumberSerializer(Class<? extends Number> rawType) {
super(rawType);
}

@Override
public void serialize(Number value, JsonGenerator gen, SerializerProvider provider) throws IOException {
// 超出范围 序列化位字符串
if (value.longValue() > MIN_SAFE_INTEGER && value.longValue() < MAX_SAFE_INTEGER) {
super.serialize(value, gen, provider);
} else {
gen.writeString(value.toString());
}
}
}

}

方式二、使用Fastjson2替换SpringMvc的全局序列化与反序列化器,并解决反序列化时Long精度丢失问题

引入依赖

<!-- spirngboot2.6.9 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>


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

SpringBoot添加配置文件

@Configuration
public class Fastjson2Webmvc implements WebMvcConfigurer {

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
FastJsonConfig config = new FastJsonConfig();
config.setCharset(StandardCharsets.UTF_8);
config.setDateFormat("yyyy-MM-dd HH:mm:ss");
config.setWriterFeatures(
//long 转 string 丢失精度问题
JSONWriter.Feature.WriteLongAsString,
// 保留map空的字段
JSONWriter.Feature.WriteMapNullValue,
//将List类型的null转成[]
JSONWriter.Feature.WriteNullListAsEmpty,
//将String类型的null转成""
JSONWriter.Feature.WriteNullStringAsEmpty,
//将Boolean类型的null转成false
JSONWriter.Feature.WriteNullBooleanAsFalse,
//日期格式转换
JSONWriter.Feature.PrettyFormat,
//将空置输出为缺省值,Number类型的null都输出为0,String类型的null输出为"",数组和Collection类型的输出为[]
JSONWriter.Feature.NullAsDefaultValue
);
fastJsonHttpMessageConverter.setFastJsonConfig(config);
converters.add(0, fastJsonHttpMessageConverter);
}

@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
FastJsonJsonView fastJsonJsonView = new FastJsonJsonView();
//自定义配置...
FastJsonConfig config = new FastJsonConfig();
config.setCharset(StandardCharsets.UTF_8);
config.setDateFormat("yyyy-MM-dd HH:mm:ss");
config.setReaderFeatures(JSONReader.Feature.FieldBased, JSONReader.Feature.SupportArrayToBean);
fastJsonJsonView.setFastJsonConfig(config);
registry.enableContentNegotiation(fastJsonJsonView);
}
}

关于FastJsonConfig的具体配置参看——>fastjson2/docs/features_cn.md at main · alibaba/fastjson2 · GitHub