资讯专栏INFORMATION COLUMN

Fastjson - 自定义过滤器(PropertyPreFilter)

everfight / 2743人阅读

摘要:是通过编程扩展的方式定制序列化。支持种,用于不同场景的定制序列化。数据格式过滤器该过滤器由提供,代码实现运行结果查看数据的过滤结果,发现中的属性也被过滤掉了,不符合需求。过滤器该自定义过滤器实现接口,实现根据层级过滤数据中的属性。

SerializeFilter是通过编程扩展的方式定制序列化。Fastjson 支持6种 SerializeFilter,用于不同场景的定制序列化。

PropertyPreFilter:根据 PropertyName 判断是否序列化

PropertyFilter:根据 PropertyName 和 PropertyValue 来判断是否序列化

NameFilter:修改 Key,如果需要修改 Key,process 返回值则可

ValueFilter:修改 Value

BeforeFilter:序列化时在最前添加内容

AfterFilter:序列化时在最后添加内容

1. 需求

JSON 数据格式如下,需要过滤掉其中 "book" 的 "price" 属性。

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
}
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 includes = new HashSet();
    private final Set excludes = new HashSet();
    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 getIncludes() {
        return includes;
    }

    public Set 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 数据的过滤结果,实现了上面的需求。

参考:http://www.cnblogs.com/dirgo/...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/70245.html

相关文章

  • 只因数据过滤,方可模拟beanutils框架

    摘要:因而,我从中也知道了,很多公司没有实现数据过滤。因为,那样将会造成数据的冗余。因而,我们这时需要过滤数据对象,如代码所示常用的把图片转成结构如上诉代码的转换,公司使用的是这个框架。而栈是存放数据的一种结构,其采用,即先进后出。 导读 上一篇文章已经详细介绍了框架与RTTI的关系,RTTI与反射之间的关系。尤其是对反射做了详细说明,很多培训机构也将其作为高级教程来讲解。 其实,我工作年限...

    yzzz 评论0 收藏0
  • FastJson几种常用场景

    JavaBean package com.daily.json; import com.alibaba.fastjson.annotation.JSONField; import java.util.Date; public class Student { @JSONField(name = NAME, ordinal = 3) private String name; ...

    Lionad-Morotar 评论0 收藏0
  • ApiBoot - ApiBoot Http Converter 使用文档

    摘要:如下所示不配置默认使用自定义是的概念,用于自定义转换实现,比如自定义格式化日期自动截取小数点等。下面提供一个的简单示例,具体的使用请参考官方文档。 ApiBoot是一款基于SpringBoot1.x,2.x的接口服务集成基础框架, 内部提供了框架的封装集成、使用扩展、自动化完成配置,让接口开发者可以选着性完成开箱即用, 不再为搭建接口框架而犯愁,从而极大...

    dance 评论0 收藏0
  • 记录_使用JSR303规范进行数据校验

    摘要:时间年月日星期三说明使用规范校验接口请求参数源码第一章理论简介背景介绍如今互联网项目都采用接口形式进行开发。该规范定义了一个元数据模型,默认的元数据来源是注解。 时间:2017年11月08日星期三说明:使用JSR303规范校验http接口请求参数 源码:https://github.com/zccodere/s... 第一章:理论简介 1-1 背景介绍 如今互联网项目都采用HTTP接口...

    187J3X1 评论0 收藏0
  • 这一次,我连 web.xml 都不要了,纯 Java 搭建 SSM 环境!

    摘要:环境要求使用纯来搭建环境,要求的版本必须在以上。即视图解析器解析文件上传等等,如果都不需要配置的话,这样就可以了。可以将一个字符串转为对象,也可以将一个对象转为字符串,实际上它的底层还是依赖于具体的库。中,默认提供了和的,分别是和。 在 Spring Boot 项目中,正常来说是不存在 XML 配置,这是因为 Spring Boot 不推荐使用 XML ,注意,并非不支持,Spring...

    liaorio 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<