当前位置: 首页 > news >正文

fastjson快速上手(4)

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

0.复杂对象解析思路

复杂的json对象的解析思路,就是一层一层的解析出JSONObject,再从JSONObject中解析出JSONObject,直到能取到需要字段为止

22d41b55169818666b66481326968d0790f.jpg

1da6ee08346565a1aa0bfd6f0248a560c9d.jpg

1. Fastjson API ParseProcess简介

ParseProcess是编程扩展定制反序列化的接口。fastjson支持如下ParseProcess:

  • ExtraProcessor 用于处理多余的字段
  • ExtraTypeProvider 用于处理多余字段时提供类型信息

2. 使用ExtraProcessor 处理多余字段

public static class VO {
    private int id;
    private Map<String, Object> attributes = new HashMap<String, Object>();
    public int getId() { return id; }
    public void setId(int id) { this.id = id;}
    public Map<String, Object> getAttributes() { return attributes;}
}

ExtraProcessor processor = new ExtraProcessor() {
    public void processExtra(Object object, String key, Object value) {
        VO vo = (VO) object;
        vo.getAttributes().put(key, value);
    }
};

VO vo = JSON.parseObject("{\"id\":123,\"name\":\"abc\"}", VO.class, processor);
Assert.assertEquals(123, vo.getId());
Assert.assertEquals("abc", vo.getAttributes().get("name"));

3. 使用ExtraTypeProvider 为多余的字段提供类型

    public static class VO {
        private int id;
        private Map<String, Object> attributes = new HashMap<String, Object>();

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public Map<String, Object> getAttributes() {
            return attributes;
        }
    }

    class MyExtraProcessor implements ExtraProcessor, ExtraTypeProvider {
        public void processExtra(Object object, String key, Object value) {
            VO vo = (VO) object;
            vo.getAttributes().put(key, value);
        }

        public Type getExtraType(Object object, String key) {
            if ("value".equals(key)) {
                return Integer.class;
            }
            return null;
        }
    }

    
    ExtraProcessor processor = new MyExtraProcessor();

    VO vo = JSON.parseObject("{\"id\":123,\"value\":\"123456\"}", VO.class, processor);
    Assert.assertEquals(123,vo.getId());
    Assert.assertEquals(123456,vo.getAttributes().get("value"));
    // value本应该是字符串类型的,通过getExtraType的处理变成Integer类型了。
    

Fastjson API SerializeFilter

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

  1. PropertyPreFilter 根据PropertyName判断是否序列化
  2. PropertyFilter 根据PropertyName和PropertyValue来判断是否序列化
  3. NameFilter 修改Key,如果需要修改Key,process返回值则可
  4. ValueFilter 修改Value
  5. BeforeFilter 序列化时在最前添加内容
  6. AfterFilter 序列化时在最后添加内容

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

  public interface PropertyFilter extends SerializeFilter {
      boolean apply(Object object, String propertyName, Object propertyValue);
  }

可以通过扩展实现根据object或者属性名称或者属性值进行判断是否需要序列化。例如:

    PropertyFilter filter = new PropertyFilter() {

        public boolean apply(Object source, String name, Object value) {
            if ("id".equals(name)) {
                int id = ((Integer) value).intValue();
                return id >= 100;
            }
            return false;
        }
    };

    JSON.toJSONString(obj, filter); // 序列化的时候传入filter

PropertyPreFilter 根据PropertyName判断是否序列化

和PropertyFilter不同只根据object和name进行判断,在调用getter之前,这样避免了getter调用可能存在的异常。

 public interface PropertyPreFilter extends SerializeFilter {
      boolean apply(JSONSerializer serializer, Object object, String name);
  }

NameFilter 序列化时修改Key

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

public interface NameFilter extends SerializeFilter {
    String process(Object object, String propertyName, Object propertyValue);
}

fastjson内置一个PascalNameFilter,用于输出将首字符大写的Pascal风格。 例如:

import com.alibaba.fastjson.serializer.PascalNameFilter;

Object obj = ...;
String jsonStr = JSON.toJSONString(obj, new PascalNameFilter());

ValueFilter 序列化是修改Value

  public interface ValueFilter extends SerializeFilter {
      Object process(Object object, String propertyName, Object propertyValue);
  }

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

在序列化对象的所有属性之前执行某些操作,例如调用 writeKeyValue 添加内容

  public abstract class BeforeFilter implements SerializeFilter {
      protected final void writeKeyValue(String key, Object value) { ... }
      // 需要实现的抽象方法,在实现中调用writeKeyValue添加内容
      public abstract void writeBefore(Object object);
  }

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

在序列化对象的所有属性之后执行某些操作,例如调用 writeKeyValue 添加内容

  public abstract class AfterFilter implements SerializeFilter {
      protected final void writeKeyValue(String key, Object value) { ... }
      // 需要实现的抽象方法,在实现中调用writeKeyValue添加内容
      public abstract void writeAfter(Object object);
  }

 

Fastjson BeanToArray

在fastjson中,支持一种叫做BeanToArray的映射模式。普通模式下,JavaBean映射成json object,BeanToArray模式映射为json array。

Sample 1

class Mode {
   public int id;
   public String name;
}

Model model = new Model();
model.id = 1001;
model.name = "gaotie";

// {"id":1001,"name":"gaotie"}
String text_normal = JSON.toJSONString(model); 

// [1001,"gaotie"]
String text_beanToArray = JSON.toJSONString(model, SerializerFeature.BeanToArray); 

// support beanToArray & normal mode
JSON.parseObject(text_beanToArray, Feature.SupportArrayToBean); 

上面的例子中,BeanToArray模式下,少了Key的输出,节省了空间,json字符串较小,性能也会更好。

Sample 2

BeanToArray可以局部使用,比如:

class Company {
     public int code;
     public List<Department> departments = new ArrayList<Department>();
}

@JSONType(serialzeFeatures=SerializerFeature.BeanToArray, parseFeatures=Feature.SupportArrayToBean)
class Department {
     public int id;
     public Stirng name;
     public Department() {}
     public Department(int id, String name) {this.id = id; this.name = name;}
}


Company company = new Company();
company.code = 100;
company.departments.add(new Department(1001, "Sales"));
company.departments.add(new Department(1002, "Financial"));

// {"code":10,"departments":[[1001,"Sales"],[1002,"Financial"]]}
String text = JSON.toJSONString(commpany); 

在这个例子中,如果Company的属性departments元素很多,局部采用BeanToArray就可以获得很好的性能,而整体又能够获得较好的可读性。

Sample 3

上一个例子也可以这样写(推荐):

class Company {
     public int code;

     @JSONField(serialzeFeatures=SerializerFeature.BeanToArray, parseFeatures=Feature.SupportArrayToBean)
     public List<Department> departments = new ArrayList<Department>();
}

性能

使用BeanToArray模式,可以获得媲美protobuf的性能。

                                   create     ser   deser   total   size  +dfl
protobuf                              244    2297    1296    3593    239   149
json/fastjson_array/databind          123    1289    1567    2856    281   163
msgpack/databind                      122    1525    2180    3705    233   146
json/fastjson/databind                120    2019    2610    4629    486   262
json/jackson+afterburner/databind     118    2142    3147    5289    485   261
json/jackson/databind                 124    2914    4411    7326    485   261

这里的json/fastjson_array/databind就是fastjson启用BeanToArray模式,total性能比protobuf好,请看fastjson Benchmark

 

转载于:https://my.oschina.net/hutaishi/blog/1523672

相关文章:

  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • Python Configparser模块读取、写入配置文件
  • Oracle JET mobile cordove navigator.app对象
  • TFS 报错解决方案:tf400324
  • 欧洲某领先银行利用大数据实现创新转型
  • Nginx多层代理配置
  • 嗜血法医第八季/全集Dexter 8迅雷下载
  • 太一星晨:负载均衡啃不动的骨头交给应用交付
  • Android之通过HttpURLConnection.getResponseCode状态码抛出异常的问题以及解决方法
  • Dropcam摄像头:透过我的眼睛辨出你是谁
  • webservice fail protected mode
  • 第20条:类层次优于标签类
  • css属性的继承、初识值、计算值、当前值、应用值
  • redis以及php的redis扩展安装部署
  • Gartner表示安全分析可能是安全风险检测的关键
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • ES6系统学习----从Apollo Client看解构赋值
  • Flex布局到底解决了什么问题
  • jquery ajax学习笔记
  • js学习笔记
  • magento2项目上线注意事项
  • nfs客户端进程变D,延伸linux的lock
  • nodejs:开发并发布一个nodejs包
  • Promise初体验
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • spring学习第二天
  • Vue.js源码(2):初探List Rendering
  • 从零搭建Koa2 Server
  • 对象引论
  • 基于webpack 的 vue 多页架构
  • 力扣(LeetCode)22
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 面试题:给你个id,去拿到name,多叉树遍历
  • 面试总结JavaScript篇
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • 做一名精致的JavaScripter 01:JavaScript简介
  • ​Spring Boot 分片上传文件
  • #LLM入门|Prompt#3.3_存储_Memory
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • $forceUpdate()函数
  • (175)FPGA门控时钟技术
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (python)数据结构---字典
  • (八)c52学习之旅-中断实验
  • (二)换源+apt-get基础配置+搜狗拼音
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • .“空心村”成因分析及解决对策122344
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .net 使用$.ajax实现从前台调用后台方法(包含静态方法和非静态方法调用)
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .NET构架之我见