Jackson在Spring Boot中的开发技巧详解

发布于:2025-07-19 ⋅ 阅读:(19) ⋅ 点赞:(0)

Jackson在Spring Boot中的开发技巧详解

Jackson 是 Spring Boot 中默认的 JSON 处理库,用于对象与 JSON 之间的序列化和反序列化。它在日常开发中扮演着重要角色,掌握其开发技巧能够显著提升开发效率和系统的稳定性。本文将详细介绍 Jackson 在 Spring Boot 中的各种开发技巧,涵盖基础配置、注解使用、自定义序列化器和反序列化器、以及处理复杂数据类型等方面。

基础配置

1. 全局配置

在 Spring Boot 中,可以通过 application.propertiesapplication.yml 文件对 Jackson 进行全局配置。

  • 日期格式化:设置日期类型的全局格式化规则,例如:
    spring:
      jackson:
        date-format: yyyy-MM-dd HH:mm:ss
        time-zone: GMT+8
    
  • Long 型字段转字符串:为了避免 JavaScript 在处理 Long 型字段时可能出现的精度丢失问题,可以将 Long 型字段序列化为字符串:
    spring:
      jackson:
        default-property-inclusion: non_null
        serialization:
          write_bigdecimal_as_plain: true
    
    或者在字段级别使用 @JsonFormat 注解:
    public class MyClass {
        @JsonFormat(shape = JsonFormat.Shape.STRING)
        private Long lng;
    }
    

2. 默认配置

Spring Boot 默认集成了 Jackson,无需额外配置即可处理 JSON。例如,使用 @RequestBody@ResponseBody 注解时,Spring Boot 会自动将 JSON 数据与 Java 对象进行转换。

注解使用

Jackson 提供了丰富的注解,用于定制化数据转换的行为。

  • @JsonProperty:指定属性在 JSON 中的名称。
  • @JsonIgnore:忽略某个属性,不进行序列化和反序列化。
  • @JsonFormat:指定日期、时间等的格式。
  • @JsonInclude:指定属性在何种条件下包含在 JSON 中,例如 non_null 表示只包含非空值。
  • @JsonCreator@JsonValue:用于指定构造函数和序列化时的值。

下面把 Jackson 中最常用的 5 个注解@JsonProperty@JsonIgnore@JsonFormat@JsonInclude@JsonCreator/@JsonValue)的
① 作用、② 常用属性、③ 典型代码示例、④ 运行效果一次讲清,拿来即用。


1. @JsonProperty —— 给 JSON 字段起别名

作用 把 Java 字段名映射成任意 JSON 键名,或反向映射
常用属性 value(JSON 键名)、required(反序列化时是否必须存在)
public class User {
    @JsonProperty("user_name")   // 序列化/反序列化都用 "user_name"
    private String userName;

    @JsonProperty(value = "age", required = true)
    private Integer age;
}

效果

{"user_name":"Tom","age":18}

2. @JsonIgnore —— 完全忽略字段

作用 序列化 & 反序列化都跳过该字段
无常用属性 直接打在字段或 getter 上即可
public class User {
    private String name;
    @JsonIgnore          // 密码不出现在 JSON 中
    private String password;
}

效果

{"name":"Tom"}

3. @JsonFormat —— 控制日期/数字/枚举格式

作用 精准控制日期、时间、数字、枚举的字符串格式
常用属性 pattern(格式模板)、timezoneshape(STRING/NUMBER)
public class Order {
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime createTime;

    @JsonFormat(shape = JsonFormat.Shape.STRING) // Long → String,防 JS 精度丢失
    private Long orderId;
}

效果

{"createTime":"2024-06-01 15:30:00","orderId":"9223372036854775807"}

4. @JsonInclude —— 条件化序列化

作用 仅当字段满足给定条件时才输出到 JSON
常用取值 NON_NULLNON_EMPTYNON_DEFAULTCUSTOM
@JsonInclude(JsonInclude.Include.NON_NULL)   // 类级别:所有 null 字段都不输出
public class User {
    private String name;
    private String email;   // 为 null 时会被忽略
}

效果(email==null)

{"name":"Tom"}

5. @JsonCreator + @JsonValue —— 自定义构造 & 单值序列化

注解 作用
@JsonCreator 反序列化:告诉 Jackson 用指定构造器/工厂方法创建对象
@JsonValue 序列化:把整个对象变成单一值(字符串、数字等)
public class Distance {
    private final int meters;

    @JsonCreator                       // 反序列化 {"distance": 1200}
    public Distance(@JsonProperty("distance") int meters) {
        this.meters = meters;
    }

    @JsonValue                       // 序列化时只返回这个数字
    public int getMeters() {
        return meters;
    }
}

序列化效果

1200

反序列化示例

{"distance":1200}new Distance(1200)

一张图速记

注解 主要场景 一句话记忆
@JsonProperty 字段名不一致 “换个名字”
@JsonIgnore 敏感/无用字段 “当它不存在”
@JsonFormat 日期/数字格式 “按模板输出”
@JsonInclude 过滤空值 “非空才要”
@JsonCreator/@JsonValue 构造/单值序列化 “对象 ↔ 单值”

把这些注解组合起来,就能覆盖 90% 的日常 JSON 定制化需求。

自定义序列化与反序列化

当注解和全局配置无法满足需求时,可以通过自定义序列化器和反序列化器来实现更复杂的功能。

1. 自定义序列化器

public class CustomDateSerializer extends JsonSerializer<Date> {
    @Override
    public void serialize(Date date, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDate = sdf.format(date);
        gen.writeString(formattedDate);
    }
}

在 Java 类中使用 @JsonSerialize 注解来指定自定义序列化器:

public class User {
    @JsonSerialize(using = CustomDateSerializer.class)
    private Date birthday;
}

2. 自定义反序列化器

public class CustomDateDeserializer extends JsonDeserializer<Date> {
    @Override
    public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonNode node = p.getCodec().readTree(p);
        String date = node.asText();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return sdf.parse(date);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }
}

在 Java 类中使用 @JsonDeserialize 注解来指定自定义反序列化器:

public class User {
    @JsonDeserialize(using = CustomDateDeserializer.class)
    private Date birthday;
}

处理复杂数据类型

1. 枚举与 JSON 的互转

在开发中,为了避免过多的魔法值,使用枚举类来封装一些静态的状态代码。例如:

public enum StatusEnums {
    NORMAL(1, "正常"),
    LOCK(2, "锁定"),
    DELETE(3, "删除");
    private Integer code;
    private String desc;
    // 构造方法、getter 和 setter
}
  • 使用 @JsonValue 注解:通过 @JsonValue 注解,可以控制枚举序列化的结果。

    @JsonValue
    public Integer getCode() {
        return code;
    }
    
  • 自定义序列化器和反序列化器:通过自定义序列化器和反序列化器,可以实现更复杂的枚举与 JSON 的互转逻辑。

2. 处理嵌套对象

Jackson 可以轻松处理嵌套对象的序列化和反序列化。例如:

public class Order {
    private Long orderId;
    private User user;
    // getter 和 setter
}

public class User {
    private Long id;
    private String name;
    // getter 和 setter
}

性能优化

1. 使用流式 API

对于大型 JSON 数据,使用流式 API(如 JsonParserJsonGenerator)可以逐步处理 JSON 数据,避免一次性加载整个 JSON 文档,从而提高性能。

2. 使用缓存机制

Jackson 内部采用了对象缓存机制,通过对象缓存可以显著提升序列化与反序列化的性能。

常见问题与解决方案

1. 循环依赖问题

如果对象之间存在循环引用,Jackson 默认会抛出异常。可以使用 @JsonManagedReference@JsonBackReference 注解来避免循环依赖。

public class Department {
    @JsonManagedReference
    private List<User> users;
}

public class User {
    @JsonBackReference
    private Department department;
}

2. 错误处理机制

在进行 JSON 处理时,可能会遇到错误。可以通过全局异常处理器捕捉并返回错误信息。


网站公告

今日签到

点亮在社区的每一天
去签到