介绍
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标准的序列化机制
文章来源:https://www.toymoban.com/news/detail-680992.html
如果有哪里说的不对,还请大佬留言指出,方便我好改正
参考博客文章来源地址https://www.toymoban.com/news/detail-680992.html
到了这里,关于JsonInclude注解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!