小心 fastjson 的这种“智能”

最近碰到一个现象或者说问题,同一个 JSON 格式的字符串,Spring 默认的 Jackson 类库解析报错,fastjson 却没报错、正常解析了。

场景大概是这样的,有个类有个日期属性,格式指定为 “yyyy-MM-dd”。

@Data
static class Person {
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") // Jackson
    @JSONField(format = "yyyy-MM-dd") // fastjson
    Date birthDay;

    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @JSONField(format = "yyyy-MM-dd")
    Date today;

    String name;
}

测试代码如下

public void testFastJson() throws JsonProcessingException {
    String json = "{\"birthDay\":\"2022710\", \"name\": \"coderbee\", \"today\":\"2022-07-10\"}";
    Person person = JSONObject.parseObject(json, Person.class);
    System.out.println(person);     // 输出解析到对象
    System.out.println(JSONObject.toJSONString(person)); // 把对象转换为 JSON 字符串,再输出。

    ObjectMapper mapper = new ObjectMapper();
    Person jacksonPerson = mapper.readValue(json, Person.class);
    System.out.println(jacksonPerson);
}

得到的结果是这样的:

Person(birthDay=Sun Jul 10 00:00:00 CST 2022, name=coderbee)
{"birthDay":"2022-07-10","name":"coderbee"}

com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.util.Date` from String "20220710": expected format "yyyy-MM-dd"
 at [Source: (String)"{"birthDay":"20220710", "name": "coderbee"}"; line: 1, column: 13] (through reference chain: net.coderbee.algorithm.SnowFlakeTest$Person["birthDay"])

可以看到 fastjson 解析没有报错,“智能”地处理了格式不正确的问题,而 jackson 报错了。
我们再看看上面输出的第二行,就是把 fastjson 解析到的对象再次转换为 JSON 字符串,可以看到 birthDay 的格式是符合代码定义的,这样的字符串与输入是不一致的。

当我把 birthDay 的字符串替换为 “2022710”,仍然没有报错,但解析到的结果是错误的了:

Person(birthDay=Thu Jan 01 08:33:42 CST 1970, name=coderbee)
{"birthDay":"1970-01-01","name":"coderbee"}

不赞成这种“智能”,该报错的时候就得报错,这样才知道传错了。最主要的是,要切换其他 JSON 实现库才不会突然报错。


欢迎关注我的微信公众号: coderbee笔记

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据