fastjson总结

1,607 阅读4分钟

应用场景

1、打印日志

把一个对象打印为json格式的字符串

log.info("入参,param:{}",JSON.toJSONString(param));

表面的需求,是打印字符串,本质的需求是把对象转换为json格式的字符串。

2、转换数据类型

比如,调用远程服务的时候,入参是json格式的字符串,json格式的字符串又细分为:

1、map

{key:value,key:value...} //对应fastjson里的JSONObject

2、list

[{key:value},{key:value}...] //对应fastjson里的JSONArray

具体需要什么数据,要看目标需求需要什么数据,无非就是两种:
1.map //对应fastjson里的JSONObject(实现了map,本质是map)
2.list //对应fastjson里的JSONArray(实现了list,本质是list)

确认了目标需求,然后剩下的,就是组装数据即可。

接口入参和出参设计

基于Http协议的接口,很多就是json格式的字符串。比如,公司风控接口,入参和参数就是基于http协议的json字符串。


步骤

1.组装数据,得到指定格式的数据

2.把指定格式的数据转换为json格式的字符串


总结

1.基于http协议的接口,入参和出参很多都是字符串。rpc协议则是对象,所以才需要二进制序列化和反序列化。

2.所谓的序列化,其实本质就是转换数据类型。只不过基于json的话,是json格式的字符串和对象互转;而rpc协议,则是对象和二进制互转。

对象转换为json格式的字符串

入参是任何类型的对象

JSON.toJSONString(Object object)

json格式的字符串转换为对象

入参是String类型;出参是fastjson里的对象类型,比如JSONObject/JSONArray,也可以是List类型。

JSON.parseObject(json格式的字符串,实体类.class)

出参是List类型。

public static <T> List<T> parseArray(String text, Class<T> clazz)

出参是map类型

//第一种方式
        Map maps = (Map)JSON.parse(str);
        System.out.println("这个是用JSON类来解析JSON字符串!!!");
        for (Object map : maps.entrySet()){
            System.out.println(((Map.Entry)map).getKey()+"     " + ((Map.Entry)map).getValue());
        }
        
        //第二种方式
        Map mapTypes = JSON.parseObject(str);
        System.out.println("这个是用JSON类的parseObject来解析JSON字符串!!!");
        for (Object obj : mapTypes.keySet()){
            System.out.println("key为:"+obj+"值为:"+mapTypes.get(obj));
        }
        
        //第三种方式
        Map mapType = JSON.parseObject(str,Map.class);
        System.out.println("这个是用JSON类,指定解析类型,来解析JSON字符串!!!");
        for (Object obj : mapType.keySet()){
            System.out.println("key为:"+obj+"值为:"+mapType.get(obj));
        }

核心和本质

json库,是为了解决json问题,json有两个问题:

1、json格式的字符串

2、对象

这个是从数据类型的维度来看json问题的。

首先,这是给数据建模,即就是有这两种数据类型。

其他的,jar里所有的类,都是为了处理这两个数据类型互转。具体来说,就是不断地转换和组装这两种数据类型。

本质是根据
1.输入数据
2.输出数据
的要求,来进行转换和组装数据。

核心类

JSON


具体数据类型的类

1.map

JSONObject

2.list

JSONList


类继承图


JSONObject和map的区别?

没有任何区别。

都是map,只不过对map进行了增强,即速度更快的处理json数据。 JSONArray也一样,只不过对list进行增强,速度更快的处理json格式的数据。

如何使用?

对象和json格式的字符串,互相转换是可逆的。

Model model = new Model(); //任意类型的对象

   String json = JSON.toJSONString(model); // serializes model to Json //对象转换为json格式的字符串

   Model model2 = JSON.parseObject(json, Model.class); // deserializes json into model2 //json格式的字符串,再转换为对象

核心类

平常我们经常用到的是JSON.toJSONString()这个静态方法来实现序列化。其实JSON是一个抽象类,该类实现了JSONAware(转为json串)和JSONStreamAware(将json串写入Appendable中)的接口,同时又是JSONArray(内部实现就是个List)和JSONObject(内部实现就是个Map)的父类。JSON.toJSONString()方法内部实现基本相同,为做某些特定配置,对外暴露的接口可能不同。该方法的实现实际托付给了JSONSerializer类。


核心类的核心方法

同样是JSON类作为反序列化入口,实现了parse()、parseObject()、parseArray()等将json串转换为java对象的静态方法。这些方法的实现,实际托付给了DefaultJSONParser类。

DefaultJSONParser类相当于序列化的JSONSerializer类,是个功能组合器,它将上层调用、反序列化配置、反序列化实现、词法解析等功能组合在一起,相当于设计模式中的外观模式,供外部统一调用。同样,我们来分析该类的几个重要成员,看看他是如何实现纷繁的反序列化功能的。


JSONArray和JSONObject的组合使用

比如,入参是json格式的字符串(数组),那么,需要的是JSONArray,而JSONArray由多个JSONObject组成。

JSONArray jsonArray = new JSONArray();

JSONObject jsonObject1 = new JSONObect();
jsonObject1.put("key1","value2");
jsonObject1.put("key2","value2");
jsonArray.add(jsonObject);

JSONObject jsonObject2 = new JSONObect();
jsonObject2.put("key1","value2");
jsonObject2.put("key2","value2");
jsonArray.add(jsonObject2);

HttpClient.调用远程方法(url,jsonArray.toString());

泛型

目标是获取list<任意实体对象>。

If the object that your are serializing/deserializing is a ParameterizedType (i.e. contains at least one type parameter and may be an array) then you must use the toJSONString(Object) or parseObject(String, Type, Feature[]) method. Here is an example for serializing and deserialing a ParameterizedType:

   String json = "[{},...]";

   Type listType = new TypeReference<List<Model>>() {}.getType();

   List<Model> modelList = JSON.parseObject(json, listType);

参考

官方git首页

官方git-文档


文章

kimmking.github.io/2017/06/06/… //关于json和fastjson的全面介绍

blog.csdn.net/swust_chenp… //源码分析

www.csdn.net/article/201… //基本介绍

segmentfault.com/a/119000001… //demo代码