FastJSON通过SerializeFilter定制序列化

文章目录

  • FastJSON通过SerializeFilter定制序列化
    • 案例
    • SimplePropertyPreFilter 过滤器(官方实现)
      • 测试demo
    • 定制PropertyPreFilter实现层级过滤
      • 测试demo

FastJSON通过SerializeFilter定制序列化

官方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属性。

SimplePropertyPreFilter 过滤器(官方实现)

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);
        }
    }
}

测试demo

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属性也被过滤掉了,不符合需求。

定制PropertyPreFilter实现层级过滤

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;
    }
    
}

测试demo

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
      }
    ]
  }
}

你可能感兴趣的:(json,java)