SpringBoot使用Jackson 序列化小妙招

本文介绍了如何在SpringBoot项目中通过配置Jackson,实现日期格式化、Long型字段转字符串、字段值选择、命名策略、非空字段控制、属性忽略、动态字段和子对象展开等常见json序列化定制需求。
摘要由CSDN通过智能技术生成

前言

SpringBoot默认使用Jackson进行json数据的序列化,在这个过程中总会有些奇奇怪怪的需求,对于这些小需求要么增加一堆配置类,要么重写方法,其实都有点杀鸡用牛刀了,那么我来列举下日常开发中这些小需求如何通过配置的形式解决。

1 值的格式化

1.1 日期类型显示为 yyyy-MM-dd HH:mm:ss

  • 字段级别配置
@Data
public class MyClass {
	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
	private LocalDateTime time1;
	
	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timeZone = "GMT+8")
	private Date time2;
}
  • 类级别配置
@Data
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timeZone = "GMT+8")
public class MyClass {
	private LocalDateTime time1;
    private Date time2;
}
  • 全局配置
spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8

1.2 Long型字段序列化成字符串

Java的Long字段在Javascript中会精度丢失,所以序列化时要将该字段序列化成String

  • 字段级别配置
@Data
public class MyClass {
	@JsonFormat(shape = JsonFormat.Shape.STRING)
	private Long lng;
}
  • 类级别配置 (会将所有的字段都以字符串形式展示)
@Data
@JsonFormat(shape = JsonFormat.Shape.STRING)
public class MyClass {
	private Long lng;
}

2 JSON字段值的选择

2.1 用某个字段值来代替对象值

使用@JsonValue注解可以在序列化时只序列化其中某一个属性的值,而不是全部对象

@Data
public class Parent {
    public int age;
    public Name name;
    
    @Data
    public static class Name {
        @JsonValue
        public String firstName;
        public String lastName;
    }
}

结果示例:{ “age”: 25, “name”: “Wang”}, 而不是 { “age”: 25, “name”: { “firstName”: “Wang”, “lastName”: “Lei”}}

3 字段名形式

3.1 字段名显示为下划线分隔形式

  • 字段级别配置
@Data
public class MyClass {
	@JsonProperty("user_name")
	private String userName;
}
  • 类级别配置
@Data
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class MyClass {
	private String userName;
}

其他形式示例

  • SnakeCaseStrategy “user_name”
  • UpperSnakeCaseStrategy “USER_NAME”
  • UpperCamelCaseStrategy “UserName”
  • LowerCamelCaseStrategy “userName”
  • LowerCaseStrategy “username”
  • LowerDotCaseStrategy “user.name”
  • KebabCaseStrategy “user-name”
  • 全局配置
spring:
  jackson:
    property-naming-strategy: SNAKE_CASE

其他形式示例

  • SNAKE_CASE “user_name”
  • UPPER_SNAKE_CASE “USER_NAME”
  • UPPER_CAMEL_CASE “UserName”
  • LOWER_CAMEL_CASE “userName”
  • LOWER_CASE “username”
  • LOWER_DOT_CASE “user.name”
  • KEBAB_CASE “user-name”

4 字段显示与忽略

4.1 只显示非空字段

@Data
public class MyClass {
	@JsonInclude(JsonInclude.Include.NON_NULL)
	private String userName;
}
  • 类级别配置
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class MyClass {
	private String userName;
}

其他筛选策略

  • ALWAYS 始终包含,和属性的值无关
  • NON_NULL 值非空的属性才会包含属性
  • NON_ABSENT 值非空的属性,或者Optional类型的属性非空
  • NON_EMPTY 空值的属性不包含
  • CUSTOM 自定义规则

4.2 忽略某个属性

使用@JsonIgnore注解可以忽略某个字段

@Data
public class Parent {
    public int age;
    public Name name;
    
    @Data
    public static class Name {
        public String firstName;
        @JsonIgnore
        public String lastName;
    }
}

结果示例: { “age”: 25, “name”: { “firstName”: “Wang”}}, 而不是 { “age”: 25, “name”: { “firstName”: “Wang”, “lastName”: “Lei”}}

4.3 动态字段

使用@JsonAnyGetter注解将会使dynamicMap中的所有key当成和userName同级别的字段,一同被序列化:

@Data
public class MyClass {
	private String userName;

    @JsonAnyGetter
	private Map<String, Object> dynamicMap;
}

而使用@JsonAnySetter在反序列化时,会把除userName以外的字段都存放在dynamicMap对象中,需要注意的是,这时dynamicMap需要初始化:

@Data
public class MyClass {
	private String userName;

    @JsonAnySetter
	private Map<String, Object> dynamicMap = new HashMap<>();
}

4.4 将子对象的内容展开到父对象

使用@JsonUnwrapped注解将会使该字段的内容展开序列化到父级:

@Data
public class Parent {
    public int age;
    
    @JsonUnwrapped
    public Name name;

    @Data
    public static class Name {
        public String firstName;
        public String lastName;
    }
}

结果示例:{ “age”: 25, “firstName”: “John”, “lastName”: “Smith”}, 而不是 { “age”: 25, “name”: { “firstName”: “John”, “lastName”: “Smith”}}

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值