JsonInclude注解

介绍

Java对象中使用JsonInclude注解来标记需要包含在JSON字符串中的属性,为实体类在接口序列化返回值时增加规则的注解

使用

注解增加在类名上时,对整个类生效;也可增加在字段上,此时只对该字段生效

注解规则

@JsonInclude注解中的规则有:

ALWAYS

ALWAYS为默认值,表示全部序列化,即默认返回全部字段,

@JsonInclude(JsonInclude.Include.ALWAYS)

NON_NULL

NON_NULL表示值为null就不序列化,即值为null的字段不返回,

@JsonInclude(JsonInclude.Include.NON_NULL)

注:1.当实例对象中有Optional或AtomicReference类型的成员变量时,如果Optional或AtomicReference引用的实例为null,用NON_NULL 不能使该字段不做序列化,此时应使用NON_ABSENT规则
2.Optional是java用来优雅处理空指针的一个特性

NON_ABSENT

NON_ABSENT可在实例对象中有Optional或AtomicReference类型的成员变量时,如果Optional或AtomicReference引用的实例为null时,也可使该字段不做序列化,同时可以排除值为null的字段,

@JsonInclude(JsonInclude.Include.NON_ABSENT)

NON_EMPTY

只有属性值不为null或者""(空字符串)的时候才会被包含在JSON字符串中

@JsonInclude(JsonInclude.Include.NON_EMPTY)

NON_DEFAULT

只有属性值不等于Java对象的默认值的时候才会被包含在JSON字符串中。

@JsonInclude(JsonInclude.Include.NON_DEFAULT)

CUSTOM

相对其他类型,CUSTOM略为复杂,这个值要配合valueFilter属性一起使用,在序列化的时候会执行CustomFilter中的的equals方法,该方法的入参就是字段的值,如果equals方法返回true,字段就不会被序列化,如果equals方法返回false时字段才会被序列化,即true时不返回,false时才返回

@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = CustomFilter.class)
private String field;

static class CustomFilter {
   @Override
   public boolean equals(Object obj) {
       // 为null,或者不是字符串就返回true,即不返回该字段
       if(null == obj || !(obj instanceof String)) {
           return true;
       }

       // 长度大于2就返回true,意味着不被序列化
       return ((String) obj).length() > 2;
   }
}

测试代码:看其他博主的测试代码,都是用使用Controller的@ResponseBody注解测试的,但我感觉太麻烦,了解了@ResponseBody注解默认使用的也是jackson将Java对象转换为JSON格式,所以这里直接使用jackson来测试

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter;
import lombok.Setter;

@JsonInclude(JsonInclude.Include.ALWAYS)
//@JsonInclude(JsonInclude.Include.NON_DEFAULT)
//@Data
//@AllArgsConstructor
//@NoArgsConstructor
//@Builder
public class TestEntity {
    @Getter
    Long id;
    @Getter
    @Setter
    String name;
    String phone;

}

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;

public static void main(String[] args) {
    ObjectMapper objectMapper = new ObjectMapper();
    try {
        TestEntity testEntity_1 = new TestEntity();
        TestEntity testEntity_2 = new TestEntity();
        testEntity_2.setName("xiaowang");
        Gson gson = new Gson();
        System.out.println(objectMapper.writeValueAsString(testEntity_1));	//{"id":null,"name":null}
        System.out.println(objectMapper.writeValueAsString(testEntity_2));	//{"id":null,"name":"xiaowang"}
        System.out.println(gson.toJson(testEntity_1));	//{}
        System.out.println(gson.toJson(testEntity_2));	//{"name":"xiaowang"}
    } catch (JsonProcessingException e) {
        System.out.println("出错了");
    }
}

之前测试时踩了点坑,没有给实体写get方法,结果上面的 testEntity_1 打印一直为{},就很纳闷,但加了lombok的@Data注解后,又打印是{"id":null,"name":null,"phone",null},就很好奇为啥,以为是toString方法导致的,后来把@Data注解去掉重写了toString方法,结果打印结果还不对,后来才明白是get方法的原因,具体解释如下:

注意:当尝试将一个Java对象序列化为JSON时,只有那些具有getter方法的属性会被包含在JSON中,因为这些属性是可以从外部访问的。

而且这里测了一下jackson和Gson的序列化结果是否一致,结果发现不一样,原因可能是:Gson使用自定义的序列化方式,而ObjectMapper使用Java标准的序列化机制

如果有哪里说的不对,还请大佬留言指出,方便我好改正
参考博客

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值