一、使用Fastjson的感受
精益编程系统,大部分都是采用Fastjson作为数据的传输,包括:参数传输与结果返回;
这样的好处相当明显:
- 大大减少了系统的中间封装类的数量,并对json属性的增加与减少提供灵活的载体;
- 统一数据格式的返回,降低对中间类的依赖;
当然…也会产生一些坏处:
- 对参数的结构,或者中间传输数据属性,标识不明显,必须要依赖说明才能知道传输有哪些属性;
- 但这个只是针对参数而言,毕竟一般的方法传参,不会太多,所以
这个缺点,本人认为可以忽略
对于结果的返回,使用json输出,已经是springboot请求响应的标配,所以方法直接使用json包装结果数据,并直接返回,作为响应json直接输出到请求方,是效率非常高的,避免了中间的【中间类的序列化】过程。
二、1跟2版本的比较
今天看了一下两个版本的重要两个类:JSONObject与JSONArray的源码,用完全重构Fastjson2来形容,一点都不过分..
1. Fastjson1继承父类定义
//1.Fastjson 1 JSONObject类定义
public class JSONObject extends JSON implements Map<String, Object> ...{
}
//2.Fastjson 1 JSONArray类定义
public class JSONArray extends JSON implements List<Object>... {
}
2. Fastjson2继承父类定义
//1.Fastjson2 JSONObject类定义
public class JSONObject extends LinkedHashMap<String, Object> implements InvocationHandler{
}
//2.Fastjson2 JSONArray类定义
public class JSONArray extends ArrayList<Object> {
}
分析(1)
- Fastjson1 的JSONObject 只是简单实现Map接口,是无序的map容器
- Fastjson2 的JSONObject 实现了链结构的Map,是有序的Map容器
- 无论是JSONObject或者JSONArray都摆脱了JSON的类,而且JSON由抽象类——>接口
三、优化Springboot默认的json序列化与反序列化
作为springboot默认的jackson,还是号称最快的json工具fastjson,对于springboot来说,都只是一个序列化的工具而已,作为一个json成熟工具,对于数据的序列与反序列,其实都有一套默认转换规则。
今天就这个换换规则来进行扩展,扩展成符合自己业务规范的转换器,最典型的就是对于Date时间的转换
1.Fastjson2对springboot的支持
详情请移步查看:Fastjson2让springboot的json序列化飞起来
文中对springboot的数据经过json序列化后的输出,制定了一个转换器规则,注意:这个是针对springboot的输出格式规则的修改,但是不是fastjson本身的转换规则的设置。
2.Fastjson2的序列化分析
JSONWriter是fastjson2序列化的底层实现,针对toJSONString和toJSONByte两种场景..
Fastjson2对实体类,集合类型等数据的序列化转换(Object->JSONObject or JSONArray),是通过JSON来完成,过程:
- String JSON.toJSONString(Object),先把对象转化为字符串..
- Object JSON.parse(String text),再把字符串的json,转为为对应的json对象
为此,我封装了一下parse的这个方法,用于转化Object->json对象(文档jSONFuncs.java)
//1.有点小问题的转换方法
public static Object parse(Object obj){
if(obj == null) {
return JSONObject.builder();
}
if(obj instanceof JSONObject) {
return (JSONObject)obj;
}
if(obj instanceof JSONArray) {
return (JSONArray)obj;
}
if(obj instanceof String) {
return JSON.parse(obj.toString());
}
if(obj instanceof Boolean) {
return JSONObject.builder();
}
//这一步使用json默认的转换器(有点小问题的)
String objStr = JSON.toJSONString(obj,JSONWriter.Feature.PrettyFormat);
if(obj instanceof Collection) {
return (JSONArray)JSON.parseObject(objStr,JSONArray.class);
}
return JSON.parseObject(objStr,JSONObject.class);
}
以上的方法,对于转换javaBean或者集合数据的时候,对Date的转换,就默认输出:ms的格式
这个时候,经过分析,是由于JSON.toJSONObject的时候,已经使用了默认转换器,已经发生点问题了
经过研究源码,可以修改为:
//这里是转换重点:JSONWriter是fastjson2序列化的底层实现,针对toJSONString和toJSONByte两种场景
JSONWriter.Context context = new JSONWriter.Context(new ObjectWriterProvider(),JSONWriter.Feature.PrettyFormat);
context.setDateFormat("yyyy-MM-dd HH:mm:ss");
String objStr = JSON.toJSONString(obj,context);
经过这样设定JSONWriter,就能对实时转换Date的使用需要的输出格式。
精益编程框架,对Fastjson2进行了不少的扩展,尽量让其发挥其功能到极致,请参考文档:Springboot使用Fastjson2转换器