问题描述
从 com.alibaba:fastjson:2.0.47 升级到 2.0.64 后,使用 Fastjson 1.x 兼容包序列化带 Jackson @JsonFormat(shape = JsonFormat.Shape.STRING) 的 BigDecimal 字段时,数值 0.47 被输出为未加引号的 string0,生成非法 JSON;随后调用 JSON.parseObject 报 illegal 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 兼容包)
重现步骤
- 引入依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.64</version>
</dependency>
- 运行以下最小复现代码:
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 输出:
随后解析失败:
com.alibaba.fastjson.JSONException: illegal input error, offset 14, character s, line 1, column 14, fastjson-version 2.0.64
期待的正确结果
应生成合法 JSON,并保持 Jackson 注解指定的字符串形式:
版本对比与临时规避
- 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。请确认这是否为回归问题,并协助修复。
问题描述
从
com.alibaba:fastjson:2.0.47升级到2.0.64后,使用 Fastjson 1.x 兼容包序列化带 Jackson@JsonFormat(shape = JsonFormat.Shape.STRING)的BigDecimal字段时,数值0.47被输出为未加引号的string0,生成非法 JSON;随后调用JSON.parseObject报illegal input error。回退到 2.0.47 后恢复正常。环境信息
com.alibaba:fastjson兼容包)重现步骤
实际结果
Fastjson 2.0.64 输出:
随后解析失败:
期待的正确结果
应生成合法 JSON,并保持 Jackson 注解指定的字符串形式:
{"examScore":"0.47"}版本对比与临时规避
{"examScore":"0.47"},可以正常反序列化。{"examScore":string0},生成非法 JSON。-Dfastjson2.useJacksonAnnotation=false后输出{"examScore":0.47}并可解析,但会全局关闭 Jackson 注解兼容,不能作为通用解决办法。初步定位
初步对比源码发现,
BeanUtils.processJacksonJsonFormat(FieldInfo, Annotation)对JsonFormat.Shape.STRING的处理发生了变化:JSONWriter.Feature.WriteNonStringValueAsString;fieldInfo.format = "string"。对
BigDecimal字段,"string"似乎被当作数值格式化模式,最终把0.47格式化为未加引号的string0。请确认这是否为回归问题,并协助修复。