Lazy loaded image
技术分享
用 Jackson 正确处理 JSON
00 min
2023-8-9
2024-11-25
type
status
date
slug
summary
tags
category
icon
password

常用注解

@JsonProperty
用于在序列化和反序列化时将对象的属性和JSON中的字段进行映射
可以用在 属性 或 getter和setter方法(两者效果一样)
 
@JsonIgnore
用于在序列化和反序列化过程中忽略属性或方法
应用场景:
  1. 保护敏感信息:有些属性可能包含敏感信息,例如用户的密码或个人身份证号码。通过在这些属性上使用 @JsonIgnore 注解,可以确保在序列化过程中不会将敏感信息暴露给外部。
  1. 控制输出字段:有时候,对象中的某些属性只在特定的情况下才需要进行序列化。通过在不需要序列化的属性上使用 @JsonIgnore 注解,可以控制输出字段的选择性。
  1. 避免循环引用:在对象之间存在循环引用关系时,序列化过程可能会导致无限递归。通过在循环引用的属性上使用 @JsonIgnore 注解,可以防止循环引用的发生,避免序列化过程中的死循环。
  1. 简化输出:有些属性可能只在内部使用,不需要在序列化结果中显示。通过在这些属性上使用 @JsonIgnore 注解,可以简化输出结果,减少不必要的字段。
  1. 隐藏内部实现细节:某些属性可能是对象内部实现的一部分,不需要对外暴露。通过在这些属性上使用 @JsonIgnore 注解,可以隐藏内部实现细节,提供更清晰和简洁的 API。
 
@JsonFormat
用于指定属性在序列化和反序列化时的格式
应用场景:
  1. 日期和时间格式化:日期和时间在数据交换和存储中非常常见。通过使用 @JsonFormat 注解,可以指定日期和时间属性的格式,以确保在序列化和反序列化过程中以一致的方式处理日期和时间。常见的日期和时间格式包括 ISO 8601 格式、自定义的日期格式模式等。
  1. 数字格式化:数值在数据传输和展示中也是常见的。@JsonFormat 注解可以用于指定数字属性的格式,例如指定小数位数、使用千位分隔符等。这样可以确保在序列化和反序列化时以一致的方式处理数字,并满足特定的展示需求。
  1. 枚举格式化:枚举类型在对象表示和持久化时经常使用。通过 @JsonFormat 注解,可以指定枚举属性的序列化形式,例如将枚举值序列化为字符串或整数形式。这对于在不同系统之间传递枚举值或持久化枚举时非常有用。
  1. 字符串格式化:字符串属性通常具有特定的格式或限制条件。@JsonFormat 注解可以用于指定字符串属性的格式和验证规则,例如指定字符串的最大长度、正则表达式验证等。这有助于确保在序列化和反序列化时对字符串进行一致的处理和验证。
 
@JsonInclude
用于在序列化过程中排除掉 空属性、默认值属性、空集合
其中 JsonInclude.Include 枚举中包含:
  1. ALWAYS: 始终包含属性,即使属性的值为默认值或空值。
  1. NON_NULL: 只包含非空属性。属性的值如果为 null,则不会包含在生成的 JSON 数据中。
  1. NON_ABSENT: 只包含非缺失属性。该选项在处理 Optional 类型的属性时特别有用,如果属性的值为 Optional.empty(),则不会包含在生成的 JSON 数据中。
  1. NON_EMPTY: 只包含非空集合属性。如果属性是集合类型,并且为空集合(如空列表或空集),则不会包含在生成的 JSON 数据中。
  1. NON_DEFAULT: 只包含与默认值不同的属性。如果属性的值与其默认值相同,则不会包含在生成的 JSON 数据中。
  1. CUSTOM: 使用自定义的值过滤器来决定属性的包含性。需要指定一个实现了 ValueFilter 接口的自定义过滤器,根据特定的条件决定是否包含属性。
  1. USE_DEFAULTS: 使用 Jackson 库的默认设置来确定属性的包含性。这是 JsonInclude 注解的默认值。
应用场景:
  1. API 响应:在构建 RESTful API 或其他类型的接口时,经常需要根据业务需求选择性地包含或排除某些属性。使用 @JsonInclude 注解,可以根据响应的需求,只包含具有特定条件或非空的属性,以生成精简和符合预期的响应数据。
  1. 数据传输对象(DTO):在应用程序的不同层之间进行数据传输时,可能需要对属性进行过滤,以避免传输不必要的数据。通过在 DTO 类中使用 @JsonInclude 注解,可以根据目标层的需求选择性地包含或排除属性,确保传输的数据具有最佳的效率和安全性。
  1. 数据库实体对象(Entity):当将实体对象持久化到数据库时,有时候需要排除某些属性,以避免将敏感或不必要的数据存储在数据库中。使用 @JsonInclude 注解,可以在序列化实体对象时选择性地排除属性,以便仅存储必要的数据。
  1. 表单校验:在表单提交或数据校验的场景中,有时候需要验证某些属性是否为空或符合特定的条件。通过在表单对象或验证实体类中使用 @JsonInclude 注解,可以根据校验规则选择性地包含或排除属性,以便进行有效的数据校验。
  1. 日志记录:在日志记录过程中,有时候需要记录特定属性的值,而忽略其他属性。使用 @JsonInclude 注解,可以选择性地包含需要记录的属性,以生成有意义的日志信息。
 
@JsonCreator
用于在反序列化过程中指定一个构造函数或静态工厂方法,以自定义对象的创建逻辑
应用场景:
  1. 处理不可变对象:如果您使用不可变对象来表示领域模型或数据传输对象(DTO),则通常无法使用默认的无参构造函数进行反序列化。通过在不可变对象的构造函数上使用 @JsonCreator 注解,可以指定一个带有参数的构造函数,使 Jackson 能够使用该构造函数来创建对象并设置属性值。
  1. 复杂的数据转换:有时候,JSON 数据的结构可能比较复杂,无法直接映射到单个对象。在这种情况下,您可以使用 @JsonCreator 注解在对象上定义一个静态工厂方法,以编写自定义的逻辑来处理复杂的数据转换。这使您能够在反序列化过程中执行额外的逻辑,并根据需要创建对象。
  1. 多态类型处理:当处理具有多态类型的对象时,@JsonCreator 注解可以用于指定创建对象的逻辑。根据不同的属性值或条件,您可以选择实例化不同的子类,并返回相应的对象。这对于处理继承关系和多态性的对象结构非常有用。
  1. 隐藏内部构造逻辑:有时候,您可能希望隐藏对象的构造细节,不希望直接通过公共构造函数创建对象。通过使用 @JsonCreator 注解和私有的构造函数或静态工厂方法,您可以将对象的创建逻辑封装起来,并在反序列化时使用这些方法。
  1. 数据校验和过滤:在反序列化过程中,您可以使用 @JsonCreator 注解来执行数据校验和过滤。通过在构造函数或静态工厂方法中添加校验逻辑,您可以验证传入的属性值是否满足特定条件,并在不满足条件时抛出异常或返回默认值。
 
@JsonAnyGetter
用于在序列化过程中动态添加自定义属性(未在对象中声明的字段)作为映射返回
此注解必须应用在返回Map类型的方法上,其中键是字段名,值是字段值
序列化为JSON:
应用场景
  1. 动态表单处理:当用户提交表单时,表单字段的数量和名称可能是不确定的。使用 @JsonAnyGetter 注解可以将动态字段作为键值对存储在 Map 中,以便于进一步处理和存储。
  1. 配置文件解析:配置文件通常具有键值对的结构,但有时也可能包含一些额外的自定义字段。使用 @JsonAnyGetter 注解可以动态地将这些自定义字段添加到配置对象中,并在需要时进行进一步处理。
  1. 日志数据解析:日志数据通常具有灵活的结构,可以包含额外的字段或属性。使用 @JsonAnyGetter 注解可以将这些额外的字段解析为动态属性,以便更灵活地处理和分析日志数据。
  1. API 响应的动态字段:当你构建一个 API,并且希望允许用户自定义一些返回结果中的字段时,可以使用 @JsonAnyGetter 注解将这些自定义字段动态地添加到 API 响应中。
  1. 数据适配和转换:当你需要将一个数据结构适配或转换为另一个数据结构时,@JsonAnyGetter 注解可以用于读取源数据的动态属性,并将其映射到目标数据结构中的对应属性。

ObjectMapper

Jackson 的 ObjectMapper 用于处理JSON数据和Java对象之间的转换
序列化 Java to JSON
反序列化 JSON to Java
特性配置

自定义序列化与反序列化器

序列化
自定义序列化器需要实现com.fasterxml.jackson.databind.JsonSerializer接口,并重写serialize方法
反序列化
自定义反序列化器需要实现com.fasterxml.jackson.databind.JsonDeserializer接口,并重写deserialize方法
注册
在使用ObjectMapper进行序列化和反序列化之前,需要将自定义的序列化器和反序列化器注册到ObjectMapper中
 
上一篇
MySQL8在CentOS7的安装与卸载
下一篇
An Introduction to Streaming on the Web