文章目录

  • 基本模型介绍
  • 序列化器
  • 注解内省器
  • 处理过程简述
  • 寻找合适的序列化器
  • 序列化器二次处理
  • 执行序列化
  • 总结


工作中经常用到json序列化,尤其是使用springboot时默认的Jackson序列化框架。 本文主要解析Jackson如何序列化带有注解的字段。

这里以Jackson中常用的@JsonFormat注解为例,目标就是将Company对象序列化。

public class Company {
    /**
     * 开张时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date openDate;

    public Date getOpenDate() {
        return openDate;
    }

    public void setOpenDate(Date openDate) {
        this.openDate = openDate;
    }
}

public class Test {
    public static void main(String[] args) {
        Company company = new Company();
        company.setOpenDate(new Date());
      
        ObjectMapper objectMapper = new ObjectMapper();

        String s;
        try {
            s = objectMapper.writeValueAsString(company);
            System.out.println(s);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

执行结果如下:
{"openDate":"2023-02-05"}

基本模型介绍

序列化器

序列化器指的是包含对某种类型的数据的序列化方式的类。如自带的有:对String类型序列化的StringSerializer,对Date类型序列化的DateSerializer,对Bean序列化的BeanSerializer。

注解内省器

注解内省器主要是用来判断 标识了注解的数据 该用什么序列化器处理。

处理过程简述

  1. 寻找合适的序列化器
  2. 序列化器二次处理(主要用于传递属性元信息)
  3. 执行序列化

寻找合适的序列化器

java json注解 日期转string jsonobject注解_ide

  1. 根据当前数据类型从缓存中获取对应的序列化器
  2. 如果获取不到,则创建序列化器
  3. 根据Company上的注解获取序列化器(Company上没有注解)
  4. 根据当前的注解内省器获取能够处理 步骤3 拿到的注解的序列化器(默认的注解内省器是JacksonAnnotationIntrospector,对于注解@JsonSerialize则返回注解指定的序列化器,对于注解JsonRawValue则返回RawSerializer
  5. 如果获取不到,再根据是否实现了JsonSerializable接口或者标注了 @JsonValue注解获取对应的序列化器(当前Company都没有)
  6. 如果没有,就只能创建通用的对象处理器BeanSerialzer
  7. 在创建BeanSerialzer之前,需要先去找到对象的属性元信息
  8. 为对象的属性(即Compnay.openDate)找到合适的序列化器(类似上面的步骤,一步一步找,这里最终没有找对于openDate属性的序列化器)
  9. 把属性元信息设置到对象元信息里,然后new一个BeanSerialzer并返回
  10. 拿到返回的序列化器以后,如果该序列化器实现了ContextualSerializer接口,则调用它的createContextual方法进行二次处理,并返回序列化器

序列化器二次处理

上面的步骤10即为序列化器二次处理:当找到合适的序列化器以后,还需要根据是否这个序列化器实现了ContextualSerializer接口,该接口声明了方法JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property)

该接口可以拿到属性的元信息,如属性上的注解信息,根据元信息可以做一些二次处理,然后再返回序列化器,再用这个返回的序列化器做序列化处理。

执行序列化

java json注解 日期转string jsonobject注解_序列化_02

  1. 序列化对象
  2. 序列化对象的字段
  3. 动态获取能处理字段的序列化器
  4. 检索内置的序列化器集合
  5. 根据类型从内置的序列化器集合获取对应的序列化器,即根据openDate的类型Date.class获取到DateSerializer
  6. 序列化器二次处理
  7. 设置需要传递到序列化器中的上下文信息
  8. openDate上的JsonFormat注解的pattern字段值传递到DateSerializer,用来在序列化openDate时知道应该转为哪种时间格式
  9. 调用DateSerializer.serialze进行字段序列化

总结

经过上面的分析,知道了Jackson如何序列化@JsonFormat标注的字段。

那能否自己定义一个注解,让Jackson通过自定义的序列化器来处理该注解标注的字段🤔️?且等下篇文章再来探究~