当前位置:   article > 正文

fastjson2 JSON反序列化时校验LocalDateTime类型数据_localdatetime json 1970

localdatetime json 1970

背景:fastjson2在处理时间日期格式时,输入非法的日期字符串字符串,转成Date、LocalDateTime等类型时,有时候不会报错,为处理这样的情况,需要增加反序列化处理。

本文使用的fastjson2版本依赖

<dependency>
  <groupId>com.alibaba.fastjson2</groupId>
  <artifactId>fastjson2</artifactId>
  <version>2.0.49</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

一、测试转换成Date类型

@Data
class A {
    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    private Date key1;
}

@Test
public void test(){
    String json1 = "{\"key1\": \"1\"}";
    // 无异常,时间格式不符合 不符合预期 结果:A(key1=Thu Jan 01 08:00:00 CST 1970)
    System.out.println(JSON.parseObject(json1, A.class));

    String json2 = "{\"key1\": \"2024-05-01\"}";
    // 无异常,时间格式不符合 不符合预期 结果:A(key1=Wed May 01 00:00:00 CST 2024)
    System.out.println(JSON.parseObject(json2, A.class));

    String json3 = "{\"key1\": \"2024-05-01 66\"}";
    // 这种情况下会抛出异常 java.time.format.DateTimeParseException: Text '2024-05-01 66' could not be parsed at index 10
    System.out.println(JSON.parseObject(json3, A.class));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

@JSONField(format = "日期格式")可以用来指定期望的时间格式,但是在某些情况下不会报错。

二、测试转换成LocalDateTime类型

@Data
class A {
    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime key1;
}
  • 1
  • 2
  • 3
  • 4
  • 5
@Test
public void test() {
     String json1 = "{\"key1\": \"1\"}";
     // 无异常,时间格式不符合 不符合预期 结果:A(key1=Thu Jan 01 08:00:00 CST 1970)
     System.out.println(JSON.parseObject(json1, A.class));

     String json2 = "{\"key1\": \"2024-05-01\"}";
     // 无异常,时间格式不符合 不符合预期 结果:A(key1=Wed May 01 00:00:00 CST 2024)
     System.out.println(JSON.parseObject(json2, A.class));

     String json3 = "{\"key1\": \"2024-05-01T00:00:00.222\"}";
     // 无异常,时间格式不符合 不符合预期 A(key1=2024-05-01T00:00:00.222)
     System.out.println(JSON.parseObject(json3, A.class));
   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

可以看到@JSONField(format = "日期格式")在解析成LocalDateTime 类型时并没有生效,查看源码中对JSONField类中format的注释:
在这里插入图片描述
说明该属性仅对Date生效,那怎么处理上述不会报错的情况呢?

三、自定义反序列化

以LocalDateTime作为参考:

public class LocalDateTimeReader implements ObjectReader<LocalDateTime> {

	public static final LocalDateTimeReader INSTANCE = new LocalDateTimeReader();

    private static final String DATE_PATTERN = "yyyy-MM-dd HH:mm:ss";

    @Override
    public LocalDateTime readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) {
        if (jsonReader.nextIfNull()) {
            return null;
        }

        String dateTimeStr = jsonReader.readString();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_PATTERN);
        LocalDateTime validDateTime;
        try {
            validDateTime =  LocalDateTime.parse(dateTimeStr, formatter);
        } catch (Exception e) {
            throw new RuntimeException(String.format("时间格式有误,请检查时间格式:%s", DATE_PATTERN));
        }
        return validDateTime;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

四、使用自定义反序列化器

在需要校验的日期格式上加上注解:

@JSONField(deserializeUsing = LocalDateTimeReader.class)
  • 1

或者全局注册(但是会影响到所有的该类型,需要慎重):

JSON.register(LocalDateTime.class, LocalDateTimeReader.INSTANCE);
  • 1

五、测试

全局注册测试
@Data
class A {
    private LocalDateTime key1;
}
  • 1
  • 2
  • 3
  • 4
@Test
public void test1() {
	JSON.register(LocalDateTime.class, LocalDateTimeReader.INSTANCE);
    String json1 = "{\"key1\": \"1\"}";
    // 有异常,时间格式不符合 符合预期 结果:com.alibaba.fastjson2.JSONException... Caused by: java.lang.RuntimeException: 时间格式有误,请检查时间格式:yyyy-MM-dd HH:mm:ss
    // System.out.println(JSON.parseObject(json1, A.class));

    String json2 = "{\"key1\": \"2024-05-01\"}";
    // 有异常,时间格式不符合 符合预期 结果:com.alibaba.fastjson2.JSONException... Caused by: java.lang.RuntimeException: 时间格式有误,请检查时间格式:yyyy-MM-dd HH:mm:ss
    // System.out.println(JSON.parseObject(json2, A.class));

    String json3 = "{\"key1\": \"2024-05-01T00:00:00.222\"}";
    // 有异常,时间格式不符合 符合预期 结果:com.alibaba.fastjson2.JSONException... Caused by: java.lang.RuntimeException: 时间格式有误,请检查时间格式:yyyy-MM-dd HH:mm:ss
    System.out.println(JSON.parseObject(json3, A.class));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
注解测试
@Data
class A {
    @JSONField(deserializeUsing = LocalDateTimeReader.class)
    private LocalDateTime key1;
}
  • 1
  • 2
  • 3
  • 4
  • 5
@Test
public void test2() {
    String json1 = "{\"key1\": \"1\"}";
    // 有异常,时间格式不符合 符合预期 结果:com.alibaba.fastjson2.JSONException... Caused by: java.lang.RuntimeException: 时间格式有误,请检查时间格式:yyyy-MM-dd HH:mm:ss
    // System.out.println(JSON.parseObject(json1, A.class));

    String json2 = "{\"key1\": \"2024-05-01\"}";
    // 有异常,时间格式不符合 符合预期 结果:com.alibaba.fastjson2.JSONException... Caused by: java.lang.RuntimeException: 时间格式有误,请检查时间格式:yyyy-MM-dd HH:mm:ss
    // System.out.println(JSON.parseObject(json2, A.class));

    String json3 = "{\"key1\": \"2024-05-01T00:00:00.222\"}";
    // 有异常,时间格式不符合 符合预期 结果:com.alibaba.fastjson2.JSONException... Caused by: java.lang.RuntimeException: 时间格式有误,请检查时间格式:yyyy-MM-dd HH:mm:ss
    System.out.println(JSON.parseObject(json3, A.class));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

测试完毕,都能够抛出异常

参考链接:
https://github.com/alibaba/fastjson2/wiki/register_custom_reader_writer_cn

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/982410
推荐阅读
相关标签
  

闽ICP备14008679号