fastjson配置及全局解决Long类型丢失精度问题

本文介绍如何在项目中配置并优化FastJSON,包括依赖引入、精度处理及序列化配置等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 引入依赖
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.56</version>
</dependency>
  1. 配置
/**
 * 使用FastJSON作为json转换
 */
@Configuration
@ConditionalOnClass({ JSON.class})
public class FastJsonHttpMessageConvertersConfig extends FastJsonHttpMessageConverter {
    /**
     * JSON转换器
     *
     * @return
     */
    @Bean
    public HttpMessageConverters fastJsonHttpMessageConverters() {
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat,
                                             SerializerFeature.WriteMapNullValue,
                                             SerializerFeature.WriteNullStringAsEmpty,
                                             SerializerFeature.WriteNullListAsEmpty,
                                             SerializerFeature.DisableCircularReferenceDetect,
                                             SerializerFeature.WriteNonStringKeyAsString
        );
        //解决Long类型丢失精度问题
        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
        serializeConfig.put(Long.class, ToStringSerializer.instance);
        serializeConfig.put(Long.TYPE, ToStringSerializer.instance);
        fastJsonConfig.setSerializeConfig(serializeConfig);
        fastConverter.setFastJsonConfig(fastJsonConfig);
        return new HttpMessageConverters(fastConverter);
    }
}
<think>嗯,用户的问题是关于解决JavaScript中Number类型长整型精度丢失问题,并提到了两种解决方案,分别是使用Jackson注解和配置JSON配置类。首先,我需要理解这个问题的背景。 JavaScript的Number类型是双精度浮点数,只能安全表示-(2^53-1)到2^53-1之间的整数。超过这个范围,比如Java中的Long类型(64位),在传输到前端时可能会丢失精度,导致后几位变成0。用户提供的两种解决方案都是针对后端序列化时把Long转为String,避免前端处理时的精度问题解决方案1中,用户提到了在VO类的id字段上使用多个注解,包括@JsonFormat(shape=STRING)和Fastjson的@JSONField。这里可能需要解释Jackson和Fastjson的区别,以及各个注解的作用。特别是@JsonFormat的Shape.STRING会把Long序列化为字符串,而@JSONField(serializeUsing)是Fastjson的序列化方式,可能用户同时使用了两种库,或者示例中有混合使用的情况? 解决方案2是通过配置类自定义Jackson的序列化方式,将Long类型统一转为String。需要解释Jackson2ObjectMapperBuilderCustomizer的作用,以及如何通过这个配置全局处理Long类型,而无需在每个字段上加注解。 用户可能混淆了Jackson和Fastjson的注解,需要指出两者的区别。例如,@JsonFormat是Jackson的注解,而@JSONField属于Fastjson。如果项目同时使用这两个库,可能会有冲突,或者用户可能是在不同的示例中分别使用它们。 另外,用户提到的@ApiModelProperty和@JsonProperty可能属于Swagger和Jackson的注解,分别用于生成API文档和属性命名映射,这些可能与问题核心关系不大,但需要简要说明。 需要确认两种解决方案的适用场景:方案1是字段级别的处理,适合个别字段需要转换的情况;方案2是全局配置,适用于所有Long类型字段都需要转换的情况。用户可能需要根据项目需求选择合适的方法。 还可能存在其他解决方案,比如前端使用字符串处理大整数,或者后端使用自定义序列化器。但用户给出了两种具体方法,需要围绕它们展开解释。 最后,确保解释清晰,避免技术术语过于晦涩,同时指出潜在的问题,比如不同JSON库的混用可能导致配置冲突,或者全局配置可能影响其他需要Long类型保持数值的情况。</think>针对JavaScript处理长整型(如JavaLong类型)时精度丢失问题,以下是两种解决方案的详细解释: ===== 问题背景 ===== JavaScript的`Number`类型最大安全整数为$2^{53}-1$(约9e15),而Java的`Long`类型是64位整数(最大值$2^{63}-1$)。当后端返回超过安全范围的Long值时,前端会出现精度丢失(如`12345678901234567`变成`12345678901234560`)。 ===== 解决方案1:字段级注解 ===== ```java @ApiModelProperty(name = "id", value = "消息id") // Swagger文档说明 @JsonProperty("id") // 定义JSON字段名 @JsonFormat(shape = JsonFormat.Shape.STRING) // Jackson将Long转为String @JSONField(serializeUsing = ToStringSerializer.class) // FastjsonLong转为String private Long id; ``` 关键点解析: 1. `@JsonFormat(shape=STRING)`:属于Jackson库,强制将数字类型序列化为字符串 2. `@JSONField(serializeUsing=...)`:属于阿里Fastjson库,作用相同 3. 注意:两个注解属于不同JSON库,通常根据项目实际使用的库二选一 ===== 解决方案2:全局配置 ===== ```java @Configuration public class JacksonConfiguration { @Bean public Jackson2ObjectMapperBuilderCustomizer customizer() { return builder -> { // 对所有Long类型字段生效 builder.serializerByType(Long.class, ToStringSerializer.instance); }; } } ``` 优势分析: 1. 一劳永逸:无需在每个字段上加注解 2. 统一处理:确保所有Long类型字段自动转为字符串 3. 兼容性:仅影响Jackson库的序列化行为 ===== 方案对比 ===== | 维度 | 字段级注解 | 全局配置 | |------------|------------------------------|----------------------------| | 影响范围 | 单个字段 | 所有Long类型字段 | | 维护成本 | 需逐个添加注解 | 一次配置终身有效 | | 灵活性 | 可针对特定字段处理 | 无法排除特殊字段 | | 适用场景 | 少量特殊字段 | 系统级统一规范 | ===== 注意事项 ===== 1. 混合使用Jackson和Fastjson时可能产生冲突,建议统一JSON库 2. 前端接收字符串后需显式转换为BigInt类型: ```javascript const id = BigInt(responseData.id); // 使用ES2020的BigInt类型 ``` 3. 数据库映射时需确保字段类型Java类型匹配(如MySQL的`BIGINT`对应Java的`Long`) 建议优先选择方案2进行全局配置,若存在个别需要保持数字格式的Long字段,可通过`@JsonFormat(shape=NUMBER)`单独覆盖。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值