官方wiki:https://github.com/alibaba/fastjson/wiki/SerializeFilter
本文将以一下json举例
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
需求:过滤掉其中book
对象的 price
属性。
package com.alibaba.fastjson.serializer;
import java.util.HashSet;
import java.util.Set;
public class SimplePropertyPreFilter implements PropertyPreFilter {
private final Class<?> clazz;
private final Set<String> includes;
private final Set<String> excludes;
private int maxLevel;
public SimplePropertyPreFilter(String... properties) {
this((Class)null, properties);
}
public SimplePropertyPreFilter(Class<?> clazz, String... properties) {
this.includes = new HashSet();
this.excludes = new HashSet();
this.maxLevel = 0;
this.clazz = clazz;
String[] var3 = properties;
int var4 = properties.length;
for(int var5 = 0; var5 < var4; ++var5) {
String item = var3[var5];
if (item != null) {
this.includes.add(item);
}
}
}
public int getMaxLevel() {
return this.maxLevel;
}
public void setMaxLevel(int maxLevel) {
this.maxLevel = maxLevel;
}
public Class<?> getClazz() {
return this.clazz;
}
public Set<String> getIncludes() {
return this.includes;
}
public Set<String> getExcludes() {
return this.excludes;
}
public boolean apply(JSONSerializer serializer, Object source, String name) {
if (source == null) {
return true;
} else if (this.clazz != null && !this.clazz.isInstance(source)) {
return true;
} else if (this.excludes.contains(name)) {
return false;
} else {
if (this.maxLevel > 0) {
int level = 0;
for(SerialContext context = serializer.context; context != null; context = context.parent) {
++level;
if (level > this.maxLevel) {
return false;
}
}
}
return this.includes.size() == 0 || this.includes.contains(name);
}
}
}
String json = "{\"store\":{\"book\":[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99}],\"bicycle\":{\"color\":\"red\",\"price\":19.95}},\"expensive\":10}";
SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
filter.getExcludes().add("price");
JSONObject jsonObject = JSON.parseObject(json);
String str = JSON.toJSONString(jsonObject, filter);
System.out.println(str);
运行结果:
{
"store": {
"bicycle": {
"color": "red",
"price": 19.95
},
"book": [
{
"author": "Nigel Rees",
"category": "reference",
"title": "Sayings of the Century"
},
{
"author": "Evelyn Waugh",
"category": "fiction",
"title": "Sword of Honour"
}
]
},
"expensive": 10
}
查看 JSON 数据的过滤结果,发现 bicycle
中的 price
属性也被过滤掉了,不符合需求。
import java.util.HashSet;
import java.util.Set;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.PropertyPreFilter;
import com.alibaba.fastjson.serializer.SerialContext;
/**
* description
*
* @author Gravity 2020/05/30 15:37
*/
public class LevelPropertyPreFilter implements PropertyPreFilter {
private final Class<?> clazz;
private final Set<String> includes = new HashSet<String>();
private final Set<String> excludes = new HashSet<String>();
private int maxLevel = 0;
public LevelPropertyPreFilter(String... properties) {
this(null, properties);
}
public LevelPropertyPreFilter(Class<?> clazz, String... properties) {
super();
this.clazz = clazz;
for (String item : properties) {
if (item != null) {
this.includes.add(item);
}
}
}
public LevelPropertyPreFilter addExcludes(String... filters) {
for (String filter : filters) {
this.getExcludes().add(filter);
}
return this;
}
public LevelPropertyPreFilter addIncludes(String... filters) {
for (String filter : filters) {
this.getIncludes().add(filter);
}
return this;
}
public boolean apply(JSONSerializer serializer, Object source, String name) {
if (source == null) { //对象为空。直接放行
return true;
}
if (clazz != null && !clazz.isInstance(source)) { //当前需要序列化的对象的类对象为空。直接放行
return true;
}
SerialContext serialContext = serializer.getContext();
String levelName = serialContext.toString();
levelName = levelName + "." + name;
levelName = levelName.replace("$.", ""); //去除开头的$.
levelName = levelName.replaceAll("\\[\\d+\\]", ""); //去除掉[] 如果是数组的话有有这个存在
if (this.excludes.contains(levelName)) { // 判断是否被排除
return false;
}
if (includes.size() == 0 || includes.contains(levelName)) { // 判断是否被开放
return true;
}
if (maxLevel > 0) {
int level = 0;
SerialContext context = serializer.getContext();
while (context != null) {
level++;
if (level > maxLevel) {
return false;
}
context = context.parent;
}
}
return false;
}
public int getMaxLevel() {
return maxLevel;
}
public void setMaxLevel(int maxLevel) {
this.maxLevel = maxLevel;
}
public Class<?> getClazz() {
return clazz;
}
public Set<String> getIncludes() {
return includes;
}
public Set<String> getExcludes() {
return excludes;
}
}
String json = "{\"store\":{\"book\":[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99}],\"bicycle\":{\"color\":\"red\",\"price\":19.95}},\"expensive\":10}";
JSONObject jsonObj = JSON.parseObject(json);
LevelPropertyPreFilter filter = new LevelPropertyPreFilter();
filter.addExcludes("store.book.price"); // 排除属性
String result = JSON.toJSONString(jsonObj, filter);
log.info(result);
运行结果
{
"store": {
"bicycle": {
"color": "red",
"price": 19.95
},
"book": [
{
"author": "Nigel Rees",
"category": "reference",
"title": "Sayings of the Century"
},
{
"author": "Evelyn Waugh",
"category": "fiction",
"title": "Sword of Honour"
}
]
},
"expensive": 10
}
同理,也可实现只返回book
对象的 price
属性。
String json = "{\"store\":{\"book\":[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99}],\"bicycle\":{\"color\":\"red\",\"price\":19.95}},\"expensive\":10}";
JSONObject jsonObj = JSON.parseObject(json);
LevelPropertyPreFilter filter = new LevelPropertyPreFilter();
filter.addIncludes("store.book.price"); // 开放属性
String result = JSON.toJSONString(jsonObj, filter);
log.info(result);
运行结果
{
"store": {
"book": [
{
"price": 8.95
},
{
"price": 12.99
}
]
}
}