环境:SpringBoot3.2.5
1. 简介
Spring Boot 提供与三个 JSON 映射库的集成:
Gson
Jackson
JSON-B
而Jackson 是首选的默认库。
本篇文章将深入学习 Jackson 注释,了解如何使用现有注释、如何创建自定义注释以及如何禁用注释。
2. 实战案例
2.1 序列化注解
@JsonAnyGetter
该注解会自动的将Map集合中的key/value映射为普通属性展示,如下示例:
public class User {private String name;private Map<String, String> properties;// getters, setters}
定义一个接口返回该User对象
("/jsonanygetter")public User jsonanygetter() {User user = new User("张三", Map.of("key1", "value1", "key2", "value2")) ;return user ;}
如上示例,在默认情况下输出结果:

将@JsonAnyGetter注解添加到properties的Getter方法上
public Map<String, String> getProperties() {return properties;}
再次方法接口,输出结果:

将Map中的key/value自动展开成为普通属性。如下配置将禁用此功能
@JsonAnyGetter(enabled = false)
这时有该注解和没有该注解将一样了,也就是默认情况。
@JsonGetter
@JsonGetter 注解是 @JsonProperty 注解的替代注解,后者将方法标记为 getter 方法,如下示例:
public class User {private String name;private Map<String, String> properties;// getters, setterspublic String info() {return "info - " + new Random().nextInt(10000) ;}}
这里并没有定义info属性,而是将info方法上添加了@JsonGetter注解,输出结果:

自动将方法名info映射为info属性输出,你也可以指定属性名:
输出的json字段将是:fullinfo。
@JsonPropertyOrder
该注解可以指定json字段的输出顺序,如下示例:
({"fullinfo", "name", "properties"})public class User {}
输出结果

输出结果为你上面指定的字段顺序。
@JsonRawValue
该注解可以指示 Jackson 按原样序列化一个属性。在下面的示例中,我们使用 @JsonRawValue 将一些自定义 JSON 作为实体的值嵌入:
public class User {private String name;private Map<String, String> properties;@JsonRawValueprivate String json ;}
接口定义
public User jsonanygetter() {User user = new User("张三", Map.of("key1", "value1", "key2", "value2")) ;user.setJson("""{"age": 22,"birhday": "1999-12-12"}""") ;return user ;}
输出结果

将字符串JSON,按照指定格式输出
@JsonValue
该注解表示将使用的单一方法,用于序列化整个实例。例如,在枚举类型中,我们为getName()方法添加了@JsonValue注解,这样任何此类实体都将通过其名称进行序列化:
public static class User {// otherprivate Gender gender = Gender.FEMALE ;}// 枚举类public enum Gender {FEMALE(1, "女"), MALE(2, "男") ;private Integer code ;private String name ;private Gender(Integer code, String name) {this.code = code ;this.name = name ;}}
有如上数据结构,输出结果如下:

接下来,我们在枚举类上的getName方法上添加@JsonValue注解,如下:
public String getName() {return name;}
输出结果

此时输出的是name属性,这可能看的还不够清楚,接下来我们在添加另外一个实体对象
public class User {// otherprivate Address address = new Address(1L, "新疆", "八楼") ;}public class Address {private Long id ;private String city ;private String details ;public String getDetails() {return details;}}
输出结果

address属性是Address对象,结果通过@JsonValue注解添加到该对象的某个属性上,结果输出的是这个属性值,而非整个对象。
@JsonSerialize
该注解用来指定自定在输出时使用的序列化器,如下示例:
public static record Person(Long id,String name,Integer age,(using = CustomDateSerializer.class) Date birthday) {}
自定义序列化
public class CustomDateSerializer extends StdSerializer<Date> {private static SimpleDateFormat sdf = new SimpleDateFormat("HH:ss");public CustomDateSerializer() {this(null);}protected CustomDateSerializer(Class<Date> t) {super(t) ;}public void serialize(Date value, JsonGenerator gen, SerializerProvider provider) throws IOException {gen.writeString(sdf.format(value)) ;}}
输出结果

2.2 反序列化注解
@JsonCreator
该注解来调整反序列化中使用的构造函数/工厂。当我们需要反序列化一些与我们需要获取的目标实体不完全匹配的 JSON 时,它就非常有用了。
public static class Order {private String orderNo ;private BigDecimal amount ;public Order(String orderNo,BigDecimal amount) {this.orderNo = orderNo ;this.amount = amount ;}}
请求结果

@JsonAnySetter
该注解允许我们灵活地使用映射作为标准属性,如下示例
public static class MockBean {private String name;private Map<String, String> properties = new HashMap<>() ;public void add(String key, String value) {properties.put(key, value);}// getters, setters}
请求输出结果

除了name属性外,其它属性自动映射到Map集合中。
@JsonSetter
该注解是 @JsonProperty 的替代方法,它将方法标记为setter方法。当我们需要读取一些 JSON 数据,但目标实体类与这些数据并不完全匹配,因此我们需要调整处理过程使其符合要求,如下示例:
public class MyObject {private Long id ;("fistName")private String name ;private String infos ;// getters, setters}
请求输出结果

@JsonAlias
该注解为反序列化过程中的属性定义了一个或多个替代名称,如下示例:
public static class AliasObject {({ "fName", "f_name", "fullName" })private String name;}
如上定义了3个别名,请求时你设置这3个别名任意一个都能被name接收。

2.3 其它实用注解
@JsonIgnoreProperties
JSON输出时会忽略配置的属性。
({"id"})public static record Customer(Long id, String name) {}
输出结果

@JsonIgnore
该注解用于忽略字段级的属性
public static record Customer( Long id, String name) {}
如上将忽略id字段的输出。
@JsonIgnoreType
该注解将会忽略指定类型下的所有属性
public static record Customer( Long id, String name, Other other) {}public static record Other(String info, String details) {}
输出结果

@JsonInclude
使用 @JsonInclude 来排除empty/null/默认值的属性。
(Include.NON_NULL)public class MyBean {public Integer id;public String name;}
测试接口
("/jsoninclude")public MyBean jsoninclude() {MyBean bean = new MyBean() ;bean.name = "中国🇨🇳" ;return bean ;}
输出结果

@JsonIncludeProperties
该注解是请求最多的 Jackson 功能之一。它在 Jackson 2.12 中引入,可用于标记一个属性或一个属性列表,Jackson 将在序列化和反序列化过程中包含这些属性。
({"name", "email"})public static class People {private String name ;private String sex ;private Integer age ;private String email;}
这将只会输出name和email属性。

@JsonFormat
该注解用来格式化日期时间,如下示例:
(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")private Date birthday = new Date();
输出将会按照给定的格式输出。否则输出的将会是时间戳。
2.4 自定义注解
我们可以使用 @JacksonAnnotationsInside注解:
// 定义了输出顺序public static Packnnotation {}public static class Pack {public Integer id ;public String name ;public String email;}
输出结果

2.5 禁用注解
通过JsonMapper.builder().disable方法可以禁止Jackson的注解,如下示例:
public static class PackObject {public Integer id ;public String name ;public String email;}
该类上添加了2个注解,一个用于控制不输出空值,一个用于控制输出顺序。
("/disableannotation")public String disableannotation() throws Exception {JsonMapper mapper = JsonMapper.builder().disable(MapperFeature.USE_ANNOTATIONS).build() ;String result = mapper.writeValueAsString(new PackObject(1, "张三", null));return result ;}
输出结果

以上是本篇文章的全部内容,如对你有帮助帮忙点赞+转发+收藏
推荐文章
优雅!SpringBoot通过函数式编程模型声明Restful API接口
完美!SpringBoot + HTML模板高效生成PDF文档
SpringBoot强大的分布式锁组件Lock4j,支持多种实现
SpringBoot自带Controller接口监控,赶紧用起来
警惕!SpringBoot错误发布事件,造成死锁Deadlock
SpringBoot3虚拟线程 & 反应式(WebFlux) & 传统Tomcat线程池 性能对比



