业务场景:数据库查询结果返回实体一共有10个属性值,但是只想把实体中的7个成员变量返回给前端,所以就需要操作忽略(隐藏)掉另外的3个成员变量
目录
1. 方法一 @JsonIgnore注解
- 作用:Jackson提供,在JSON序列化时将实体中的一些属性忽略掉,标记在属性或者方法上,返回的JSON数据就不包含被@JsonIgnore标注的属性。
注意:被标注字段无论是序列化(POJO转为JSON),还是反序列化(JSON转为POJO)都会被忽略。
代码示例
- 以下实体中的bzrsList(编制人员列表)属性是业务属性(数据库查询得到),需要经过处理后把得到的值赋给bzrsTotal(编制人员总数),然后将bzrsTotal(编制人员总数)返回给前端;
public class Demo implements Serializable {
// 单位id
private String id;
// 单位名称
private String deptName;
// 单位性质
private String deptClassValue;
// 编制人员列表
private String bzrsList;
// 编制人员总数
private int bzrsTotal;
// 使用面积正常人数
private String zcrsTotal;
// 使用面积超标人数
private String cbrsTotal;
// 正常使用面积总数
private String zcmjTotal;
// 超标使用面积总数
private String cbmjTotal;
}
- 不忽略bzrsList(编制人员列表)返回结果:
示例结果
- 使用 @JsonIgnore标注需要隐藏的成员变量
//...以上代码省略
// 编制人员列表
@JsonIgnore
private String bzrsList;
//...以下代码省略
- 运行结果bzrsList属性不再返回:
2. 方法二 @JsonIgnoreProperties注解
@JsonIgnoreProperties
相比 @JsonIgnore
更加强大,通常该注解常用于标记到POJO之上。
作用:
- 忽略多个字段,配置
value
属性即可。 - 忽略未知的属性,配置
ignoreUnknown
为true
,默认不忽略。 - 允许忽略字段被序列化,配置
allowGetters
为true
,序列化的时候不会被忽略。 - 允许忽略字段被反序列化,配置
allowSetters
为true
,反序列化的时候不会被忽略
例如需要对POJO中的多个属性进行忽略操作:
@JsonIgnoreProperties({"bzrsList", "bzrsTotal"})
3. 方法三 @JsonProperty注解
@JsonProperty 使用要求 Jackson 版本不低于 2.6
作用:给JSON的字段起别名或者设置默认值使用。
属性别名
例如需要给 deptName
属性需要对应JSON中的 dept_name
就可以使用 value
来进行别名设置。
@JsonProperty(value = "dept_name")
private String deptName;
属性忽略
在 Jackson 2.6 版本以后,这个注解也能实现忽略字段的作用。它有个 access
属性,用来指定在序列化(“读取”)和反序列化(“写”)期间访问权限(这里的读写是以属性为视角)。它由枚举Access定义:
public enum Access
{
/**
* 无论是序列化还是反序列化都会根据配置自动的处理,这个也是默认值。
*/
AUTO,
/**
* 意味着该属性只能在进行序列化时读取(通过“ getter”方法访问的值,或者从字段中读取),而在反序列化
* 期间不能写入(设置)。换句话说,这将反映“只读POJO”,其中包含的值可以读取但不能写入。
*/
READ_ONLY,
/**
* 意味着该属性只能作为反序列化的一部分写入(设置)(使用“ setter”方法,或分配给Field,或作为
* Creator参数传递),而不会被读取(获取)以进行序列化,即,该属性的值不包括在序列化中。
*/
WRITE_ONLY,
/**
* 即可读也可写,READ_ONLY 与 WRITE_ONLY 的合并效果。
*/
READ_WRITE
;
}
所以由 Access
类 可以知道,如果需要POJO 转 JSON 时,需要忽略某某属性,就可以这么操作:
@JsonProperty( access = JsonProperty.Access.WRITE_ONLY)
private String bzrsList;
4. 方法四 @JsonIgnoreType 注解
作用:被标注类作为别的类的成员属性时,该成员属性忽略序列化和反序列化。
如果上面的 Demo
类是另外一个 POJO 中的属性,我们不希望它被序列化和反序列化,那么就可以:
class UserEntity {
private Integer id;
private String name;
private Integer age;
private Role role;
// 省略getter/setter
}
class Role {
private String name;
private String Permission;
// 省略getter/setter
}
class MerchantApiApplicationTest1 {
static UserEntity userEntity;
@BeforeEach
void setUp() {
Role role = new Role();
role.setName("SUPER_ADMIN");
role.setPermission("ALL");
UserEntity user = new UserEntity();
user.setId(1);
user.setName("张三");
user.setAge(35);
user.setRole(role);
userEntity = user;
}
@Test
public void test2() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
//序列化
String json = mapper.writeValueAsString(userEntity);
System.out.println(json);
//反序列化
UserEntity readValue = mapper.readValue(json, UserEntity.class);
System.out.println("id:"+readValue.getId());
System.out.println("name:"+readValue.getName());
System.out.println("age:"+readValue.getAge());
System.out.println("role-name:"+readValue.getRole().getName());
System.out.println("role-Permission:"+readValue.getRole().getPermission());
}
@AfterEach
void tearDown() {
userEntity = null;
}
}
示例结果:
Role.class
不标注 @JsonIgnoreType
:
{"id":1,"name":"张三","age":35,"role":{"name":"SUPER_ADMIN","permission":"ALL"}}
- -------------------------------
id:1
name:张三
age:35
role-name:SUPER_ADMIN
role-Permission:ALL
Role.class
标注 @JsonIgnoreType
:
{"id":1,"name":"张三","age":35}
- -------------------------------
id:1
name:张三
age:35