SerializeFilter是通过编程扩展的方式定制序列化。Fastjson 支持6种 SerializeFilter,用于不同场景的定制序列化。
-
PropertyPreFilter:根据 PropertyName 判断是否序列化
-
PropertyFilter:根据 PropertyName 和 PropertyValue 来判断是否序列化
-
NameFilter:修改 Key,如果需要修改 Key,process 返回值则可
-
ValueFilter:修改 Value
-
BeforeFilter:序列化时在最前添加内容
-
AfterFilter:序列化时在最后添加内容
1、需求
JSON 数据格式如下,需要过滤掉其中 "book" 的 "price" 属性
{ "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 }
2、SimplePropertyPreFilter过滤器
该过滤器由 Fastjson 提供,代码实现:
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" }, "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" 属性也被过滤掉了,不符合需求
3、LevelPropertyPreFilter过滤器
该自定义过滤器实现 PropertyPreFilter 接口,实现根据层级过滤 JSON 数据中的属性
扩展类:
/** * 层级属性删除 * * @author yinjianwei * @date 2017年8月24日 下午3:55:19 * */ 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 (int i = 0; i < filters.length; i++) { this.getExcludes().add(filters[i]); } return this; } public LevelPropertyPreFilter addIncludes(String... filters) { for (int i = 0; i < filters.length; i++) { this.getIncludes().add(filters[i]); } return this; } public boolean apply(JSONSerializer serializer, Object source, String name) { if (source == null) { return true; } if (clazz != null && !clazz.isInstance(source)) { return true; } // 过滤带层级属性(store.book.price) 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 (maxLevel > 0) { int level = 0; SerialContext context = serializer.getContext(); while (context != null) { level++; if (level > maxLevel) { return false; } context = context.parent; } } if (includes.size() == 0 || includes.contains(name)) { return true; } 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; } }
代码实现:
public static void main(String[] args) { 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 propertyPreFilter = new LevelPropertyPreFilter(); propertyPreFilter.addExcludes("store.book.price"); String json2 = JSON.toJSONString(jsonObj, propertyPreFilter); System.out.println(json2); }
结果:
{ "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 数据的过滤结果,实现了上面的需求
4、不输出空数组
在我们平时开发过程中,Java bean 转JSON的时候有一些空数组,导致转换后的多了很多 “无用” 的数据
{ student:{ "name":"江南也少", "score": [] } }
这个时候我们希望这个没有参加考试,也没有分的同学,不用输出score,该怎么办呢?
我们可以定义一个Filter类
public class NotWriteEmptyList implement{ @Override public boolean apply(Object o, String key, Object value) { if (value == null) { return false; } if(value instanceof String && ((String) value).isEmpty()){ return false; } if(value instanceof List && ((List) value).size() == 0){ return false; } return true; } }
在我们同String的时候new 一个Filter 传进去就OK了
JSON.toJSONString(entity, new NotWriteEmptyList());
这样就会得到如下的结果:
{ student:{ "name":"江南也少" } }
参考:https://segmentfault.com/a/1190000010859580
https://www.cnblogs.com/sandyyeh/p/13942685.html