Jackson反序列化Date格式源码分析

本文深入分析了Jackson反序列化Date时的默认处理方式,并提出了两种自定义反序列化方法,其中方法二是通过继承StdDateFormat,替换默认的parseDate方法,实现更加优雅的扩展。同时,文章详细阐述了Jackson反序列化过程,包括查找反序列化器、处理注解等步骤。
摘要由CSDN通过智能技术生成

一,背景介绍

鉴于之前fastjson的黑历史,慢慢的就把json处理交给了Jackson。当然要对Jackson动手,需要先了解一下常规用法:

序列化和反序列化:

public class JSON {
   
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
            .setSerializationInclusion(JsonInclude.Include.NON_NULL)
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    /**
     * 将对象输出为json字符串
     *
     * @param object       对象
     * @param prettyFormat 美化格式
     * @return
     */
    public static String toJSONString(Object object, boolean prettyFormat) {
   
        try {
   
            if (prettyFormat) {
   
                return OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(object);
            }
            return OBJECT_MAPPER.writeValueAsString(object);
        } catch (Throwable e) {
   
            throw new JSONException(e);
        }
    }
   /**
     * 反序列化解析为指定类
     *
     * @param text
     * @param clazz
     * @param <T>
     * @return
     */
   public static <T> T parse(String text, Class<T> clazz) {
   
       if (text == null || text.isEmpty()) {
   
           return null;
       }
       try {
   
           return OBJECT_MAPPER.readValue(text, clazz);
       } catch (Throwable e) {
   
           throw new JSONException(e);
       }
    }
 }

如果遇到例如Date格式,则需要在对应的属性名上增加注解,例如:@JsonFormat来指定格式交由Jacson反序列化,或者@JsonDeserialize来指定自定义反序列化。

我们以@JsonDeserialize为例:

要将带有Date的json串自定义反序列化,一般情况下是继承JsonDeserializer,然后重写deserialize方法:

public class SimpleDateDeserializer extends JsonDeserializer<Date> {
   

    private static final String[] PARSE_PATTERNS = new String[]{
   
            "yyyy-MM-dd HH:mm:ss",
            "yyyy-MM-dd"};

    @Override
    public Date deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
   
		//这里增加了对时间戳的反序列化
        int tokenId = jp.getCurrentTokenId();
        if (tokenId == JsonTokenId.ID_NUMBER_INT) {
   
            return new Date(jp.getValueAsLong());
        }
        try {
   
            String value = jp.getValueAsString();
            return value == null ? null : DateUtils.parseDate(value, PARSE_PATTERNS);
        } catch (ParseException e) {
   
            throw new IOException(e);
        }
    }
}

缺点也显而易见,只支持三种格式,时间戳,时间日期,日期,其实除了时间戳,反序列化的瓶颈在于任何时间的属性,都要在字段上增加以上的两个注解,如果不加注解呢?如果是Date的toString()方法呢?答案是解析失败。

二,解决方法

先看结果:

方法一:

//一般的ObjectMapper类 
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
            .setSerializationInclusion(JsonInclude.Include.NON_NULL)
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
            .registerModule
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值