• FastJson 自定义过滤器 不输出空数组


    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

  • 相关阅读:
    socket网络编程
    Oracle 分区表 总结
    修改配置文件后不重启程序即时生效
    vue 计算属性
    Vue属性绑定指令 vbind
    vue虚拟dom
    vueslot插槽
    将博客搬至CSDN
    打造山寨手机中的App Store斯凯MiniJ(mrp)诞生记
    【教程】查看某个程序的占用的端口
  • 原文地址:https://www.cnblogs.com/tangmj/p/15960449.html
Copyright © 2020-2023  润新知