1.通过注解指定不需要序列化的字段
在不需要序列化的字段,添加@JSONField(serialize = false)
注解可进行排除。
public class DontSerializeAnnotation {
@JSONField(serialize = false)
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
* 通过注解指定不需要序列化的字段:@JSONField(serialize = false)
*/
@Test
public void testDontSerializeAnnotation() {
DontSerializeAnnotation guestUser = new DontSerializeAnnotation();
guestUser.setId(2L);
guestUser.setName("guest");
System.out.println(JSON.toJSONString(guestUser));
}
执行结果:
{"name":"guest"}
2.声明为transient的变量不进行序列化
如果被序列化的字段使用transient修饰,则不会被序列化。
public class TransientObject {
private Long id;
private transient String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
* 声明为transient的变量不进行序列化
*/
@Test
public void testTransientObject() {
TransientObject guestUser = new TransientObject();
guestUser.setId(2L);
guestUser.setName("guest");
System.out.println(JSON.toJSONString(guestUser));
}
执行结果:
{"id":2}
3.使用属性过滤器排除不需要序列化的字段
使用过滤器SimplePropertyPreFilter,可以一次性设置1到多个需要过滤掉的字段。
3.1 过滤对象中的某个字段
public class User {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
* 使用属性过滤器排除不需要序列化的字段
*/
@Test
public void testExcludeSingleFilter() {
User guestUser = new User();
guestUser.setId(2L);
guestUser.setName("guest");
SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
filter.getExcludes().add("name"); // 排除字段名为name的字段
System.out.println(JSON.toJSONString(guestUser, filter));
}
执行结果:
{"id":2}
3.2 过滤嵌套类中的相同名字的字段
Group中的User,参照上一小节。
public class Group {
private Long id;
private String name;
private List<User> users = new ArrayList<User>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
public void addUser(User user) {
users.add(user);
}
}
/**
* 使用属性过滤器排除不需要序列化的字段.
* 对于嵌套多层的类,不同类中具有相同名称的字段都会被过滤掉。
*/
@Test
public void testExcludeEmbedFilter() {
Group group = new Group();
group.setId(0L);
group.setName("admin");
User guestUser = new User();
guestUser.setId(2L);
guestUser.setName("guest");
User rootUser = new User();
rootUser.setId(3L);
rootUser.setName("root");
group.addUser(guestUser);
group.addUser(rootUser);
SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
filter.getExcludes().add("name");
System.out.println(JSON.toJSONString(group, filter));
}
执行结果:
{"id":0,"users":[{"id":2},{"id":3}]}
3.3 使用多个属性过滤器排除不需要序列化的字段
如果只想过滤特定类中的字段,可以在创建过滤器的时候,指定对应类的class对象和字段。
下面示例,分别对Group和User创建一个过滤器,过滤掉不同的字段。
/**
* 使用多个属性过滤器排除不需要序列化的字段.
*/
@Test
public void testExcludeMultiFilter() {
Group group = new Group();
group.setId(0L);
group.setName("admin");
User guestUser = new User();
guestUser.setId(2L);
guestUser.setName("guest");
User rootUser = new User();
rootUser.setId(3L);
rootUser.setName("root");
group.addUser(guestUser);
group.addUser(rootUser);
// Group的过滤器,过滤掉id字段
SimplePropertyPreFilter filter1 = new SimplePropertyPreFilter(Group.class);
filter1.getExcludes().add("id");
// User的过滤器,过滤掉name字段
SimplePropertyPreFilter filter2 = new SimplePropertyPreFilter(User.class);
filter2.getExcludes().add("name");
System.out.println(JSON.toJSONString(group, new SimplePropertyPreFilter[] {filter1, filter2}));
}
执行结果:
{"name":"admin","users":[{"id":2},{"id":3}]}
4.使用属性过滤器包含需要序列化的字段.
有些时候,我们仅仅需要序列化个别字段,或者当需要排除的字段比序列化的字段还要多的时候,这时可以使用包含而非排除的过滤器。
/**
* 使用属性过滤器包含需要序列化的字段.
*/
@Test
public void testIncludeMultiFilter() {
Group group = new Group();
group.setId(0L);
group.setName("admin");
User guestUser = new User();
guestUser.setId(2L);
guestUser.setName("guest");
User rootUser = new User();
rootUser.setId(3L);
rootUser.setName("root");
group.addUser(guestUser);
group.addUser(rootUser);
// Group只序列化id和users
SimplePropertyPreFilter filter1 = new SimplePropertyPreFilter(Group.class, "id", "users");
// User只序列化name
SimplePropertyPreFilter filter2 = new SimplePropertyPreFilter(User.class);
filter2.getIncludes().add("name");
System.out.println(JSON.toJSONString(group, new SimplePropertyPreFilter[] {filter1, filter2}));
}
执行结果:
{"id":0,"users":[{"name":"guest"},{"name":"root"}]}
5.自定义属性过滤规则
在某些特殊的场景下,以上简单的排除或包含方式,并不能很好的满足实际的应用需求。
这时,可以考虑通过自定义属性过滤器,来实现过滤。这种实现方式非常灵活,可以根据实际的需求进行实现。
可以对类、字段名和字段值执行某种规则判断,来决定是否需要进行序列化。
具体方法,是实现PropertyFilter接口中的apply方法,返回true表示包含该字段,返回false表示过滤掉。
/**
* @author wenshao[[email protected]]
*/
public interface PropertyFilter extends SerializeFilter {
/**
* @param object the owner of the property. 字段所属的对象
* @param name the name of the property. 字段名
* @param value the value of the property. 字段值
* @return true if the property will be included, false if to be filtered out
*/
boolean apply(Object object, String name, Object value);
}
/**
* 自定义属性过滤规则,最灵活的一种实现字段和值过滤的方式。
*/
@Test
public void testPropertyFilter() {
Group group = new Group();
group.setId(0L);
group.setName("admin");
User guestUser = new User();
guestUser.setId(2L);
guestUser.setName("guest");
User rootUser = new User();
rootUser.setId(3L);
rootUser.setName("root");
group.addUser(guestUser);
group.addUser(rootUser);
PropertyFilter filter = new PropertyFilter() {
@Override
public boolean apply(Object object, String name, Object value) {
//System.out.println(object + " " + name + " " + value);
if (name.equals("name")) {
return false; // 排除名为name的字段
}
if (value.toString().equals("2")) {
return false; // 排除值为2的字段
}
return true; // 包含该字段或值
}
};
System.out.println(JSON.toJSONString(group, filter));
}
执行结果:
{"id":0,"users":[{},{"id":3}]}