Skip to content

[BUG] 2.0.64 序列化带 @JsonFormat(shape = STRING) 的 BigDecimal 时生成非法 JSON #7837

Description

@innocent886

问题描述

com.alibaba:fastjson:2.0.47 升级到 2.0.64 后,使用 Fastjson 1.x 兼容包序列化带 Jackson @JsonFormat(shape = JsonFormat.Shape.STRING)BigDecimal 字段时,数值 0.47 被输出为未加引号的 string0,生成非法 JSON;随后调用 JSON.parseObjectillegal input error。回退到 2.0.47 后恢复正常。

环境信息

  • OS 信息:Windows
  • JDK 信息:JDK 1.8.0_162
  • Spring Boot:2.3.12.RELEASE
  • 版本信息:Fastjson 2.0.64(com.alibaba:fastjson 兼容包)

重现步骤

  1. 引入依赖:
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>2.0.64</version>
</dependency>
  1. 运行以下最小复现代码:
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonFormat;

import java.math.BigDecimal;

public class FastjsonJacksonFormatBigDecimalTest {

    public static class Bean {
        @JsonFormat(shape = JsonFormat.Shape.STRING)
        public BigDecimal examScore = new BigDecimal("0.47");
    }

    public static void main(String[] args) {
        String json = JSON.toJSONString(new Bean());
        System.out.println(json);
        JSON.parseObject(json, Bean.class);
    }
}

实际结果

Fastjson 2.0.64 输出:

{"examScore":string0}

随后解析失败:

com.alibaba.fastjson.JSONException: illegal input error, offset 14, character s, line 1, column 14, fastjson-version 2.0.64

期待的正确结果

应生成合法 JSON,并保持 Jackson 注解指定的字符串形式:

{"examScore":"0.47"}

版本对比与临时规避

  • 2.0.47 输出 {"examScore":"0.47"},可以正常反序列化。
  • 2.0.64 输出 {"examScore":string0},生成非法 JSON。
  • 2.0.64 添加 JVM 参数 -Dfastjson2.useJacksonAnnotation=false 后输出 {"examScore":0.47} 并可解析,但会全局关闭 Jackson 注解兼容,不能作为通用解决办法。
  • 当前临时回退并固定在 2.0.47。

初步定位

初步对比源码发现,BeanUtils.processJacksonJsonFormat(FieldInfo, Annotation)JsonFormat.Shape.STRING 的处理发生了变化:

  • 2.0.47 使用 JSONWriter.Feature.WriteNonStringValueAsString
  • 2.0.64 设置 fieldInfo.format = "string"

BigDecimal 字段,"string" 似乎被当作数值格式化模式,最终把 0.47 格式化为未加引号的 string0。请确认这是否为回归问题,并协助修复。

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions