Jackson 是一个用于 Java 平台的开源 JSON 库,它提供了灵活且高效的方式来处理 JSON 数据的序列化(Java对象 → JSON字符串)和反序列化(JSON 字符串→ Java对象)。
以下是 Jackson 的一些主要特点和功能:
-
高性能:Jackson 通过使用基于流的处理模型和性能优化技术,提供了出色的性能。它支持快速的数据绑定和处理大型 JSON 数据。
-
灵活性:Jackson 支持多种数据格式,包括 JSON、Smile(二进制 JSON 格式)和 XML。它可以处理复杂的对象关系和嵌套结构,并支持自定义序列化和反序列化规则。
-
注解支持:Jackson 提供了一系列注解(如
@JsonProperty
、@JsonIgnore
、@JsonFormat
等)来控制序列化和反序列化的行为。通过注解,你可以指定字段名称、忽略特定字段、格式化日期和时间等。 -
支持泛型和多态:Jackson 支持序列化和反序列化泛型类型,以及处理多态类型的对象。它提供了类型擦除解决方案和多态类型的标记(如
@JsonTypeInfo
、@JsonSubTypes
等)。 -
可定制性:Jackson 提供了丰富的配置选项和可扩展的 API,使你能够根据需求进行定制。你可以自定义序列化器和反序列化器,注册模块扩展功能,以及处理特定的数据转换和验证逻辑。
-
整合性:Jackson 可以与各种 Java 框架和库进行无缝集成,如 Spring、Hibernate、JAX-RS 等。它可以轻松地与其他库一起使用,以提供全面的数据处理解决方案。
Spring MVC 默认使用 Jackson 库进行 JSON 的序列化和反序列化,无需额外的配置。
当你返回一个对象时,Spring MVC 将自动使用 Jackson 库将该对象序列化为 JSON 字符串,并将其作为响应的主体返回给客户端。
同样地,当你使用 @RequestBody
注解标记的方法参数时,Spring MVC 将使用 Jackson 库将请求体中的 JSON 数据反序列化为对应的 Java 对象。
SpringBoot项目自动依赖了 Jackson 库。 非SpringBoot项目,使用 Jackson 库,可能需要在项目中添加 Jackson 库依赖。
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.5</version> </dependency>
View Code
下面是一个使用 Jackson 库进行对象序列化和反序列化的示例
package jstudy.jackson; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Data; /** * 使用 Jackson 库进行对象序列化和反序列化的示例类 */ public class JacksonSerializationDemo { public static void main(String[] args) { // 创建一个 ObjectMapper 对象 ObjectMapper objectMapper = new ObjectMapper(); // 创建一个示例对象 Person person = new Person("John Doe", 30); try { // 对象序列化为 JSON 字符串 String json = objectMapper.writeValueAsString(person); System.out.println("Serialized JSON: " + json); // JSON 字符串反序列化为对象 Person deserializedPerson = objectMapper.readValue(json, Person.class); System.out.println("Deserialized Person: " + deserializedPerson); } catch (JsonProcessingException e) { e.printStackTrace(); } } @Data static class Person { private String name; private Integer age; private String address; // 必须提供默认构造函数,以便 Jackson 库能够实例化对象 public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } } }
代码运行结果:
Serialized JSON: {“name”:”John Doe”,”age”:30,”address”:null}
Deserialized Person: JacksonSerializationDemo.Person(name=John Doe, age=30, address=null)
BTW,上面示例类 JacksonSerializationDemo 可以rename为 JacksonCodecDemo
“Codec” 一词通常用于指代编码器-解码器(Encoder-Decoder)或编码-解码(Encode-Decode)的概念。将示例重命名为 “JacksonCodecDemo” 可以更准确地表达其涵盖了序列化和反序列化的功能,强调了 Jackson 库不仅实现了对象到 JSON 的序列化(即编码)功能,还具备将 JSON 转换回对象的反序列化(即解码)功能。
这种重命名方式能够更清晰地传达代码示例的目的。
日常开发中,我们也要关注命名。良好的命名规范是高质量代码的基石之一。在 Java 中,命名规范不仅帮助保持代码的整洁性和一致性,还能极大地提高代码的可读性和可维护性。
如何控制 Jackson 在序列化对象时不包含全是 null 的字段?
要在 Jackson 中避免序列化全是 null 的字段,你可以使用 Jackson 的配置选项来控制序列化行为。
以下是两种常用的方法:
1. 使用 ObjectMapper 的 setSerializationInclusion
方法设置序列化包含规则为 JsonInclude.Include.NON_NULL
。这意味着只有非空字段才会被序列化,而全是 null 的字段将被忽略。
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; public class JacksonSerializationDemo { public static void main(String[] args) { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // ... 省略其他代码 ... } }
2. 使用 @JsonInclude
注解在类级别设置序列化包含规则为 JsonInclude.Include.NON_NULL
。这将仅对被注解的类有效。
import com.fasterxml.jackson.annotation.JsonInclude; @JsonInclude(JsonInclude.Include.NON_NULL) public class Person { // ... 省略其他代码 ... }
设置 JsonInclude.Include.NON_NULL 后,SpringMVC返回示例:
— ↓只给一列赋值的情况
[{“name”:”张三01721786586338″},{“name”:”张三11721786586338″},{“name”:”张三21721786586338″}]
— ↓如果字段为null,则不序列化
[{“name”:”张三01721787159065″},{},{“name”:”张三21721787159065″}]
— ↓同样,下面是给两列赋值时,只有第二个元素的sex不为null的情况
[{“name”:”张三01721786586338″},{“name”:”张三11721786586338″,”sex”:”male”},{“name”:”张三21721786586338″}]
BTW,我司系统是前后端分离模式,为提高开发效率,我们约定给前端页面所提供的后端接口,只返回明确需要的字段。例如:
企业客户信息,后端有一个 EnterpriseVO,包含了企业的基本信息和资质信息。不过,查询企业客户基本信息的API、查询企业客户资质信息的API、查询企业编码和企业名称的API,不能返回 EnterpriseVO 的所有字段。此时,要满足这个就可以用上面的 Jackson不序列化null字段的技术来解决。
暂无评论内容