时间过得真快, 半年又过去了。
今天得益有空, 正好写篇博文。
数据交换格式
什么是数据交换格式?
通俗一点就是服务器端与客户端之间进行数据传输与交换的格式。
我们遇到的 JSON
、XML
是最常见的数据交换格式。
<user>
<id>1</id>
<name>kraity</name>
</user>
{
"id": 1,
"name": "kraity"
}
它们都有各自的优点和缺点, XML
格式臃肿、体积大, JSON
格式清晰、体积小。
可能还有小伙伴说 ProtoBuf
, 但是 ProtoBuf
与 JSON
、XML
不配对,
因为 ProtoBuf
需要定义数据结构, 可以算得上是一种协议。
message User {
int32 id = 1;
string name = 2;
}
上面定义了一个 Proto
, 可以看出没有包含我们塞入的数据。
产品需求
南博是一个写作客户端软件, 那么可能也会用一些数据交换格式,
我们可以发现南博4.0使用了原创一种数据交换格式KAT。
我们都知道, 南博上古版本都是使用一种叫 XML-RPC
框架来完成南博与博客之间的数据交换, 可见使用的是 XML
。
经过一两年的发展, 我们意识到了解析速度和数据大小问题, 不得不寻找另外一种交换格式。
肯定首先想到是 JSON
, 南博客户端采用的是 Java
语言原生开发, 那我们首先寻找的就是 JSON
库。
在 Java
领域里, JSON
库比较出名的有 Fastjson
、Jackson
、Gson
。
根据我们已有代码情况切换另外一个库, 经过我们测试筛选, 没有选出完美符合南博当前环境下平滑的切换的JSON库。
然后我们突发奇想, 为什么我们不自己写一个JSON
库呢! 于是我们动手就干。 当库写到十分之一时候,
又想到为什么我们一定要选择 JSON
呢, 为什么不原创一种数据交换格式, 设计上对 Java
友好即多类型数据。
于是, 我们参考了 JSON
和 Java
。 拟定了一种格式, 至今还是采用当时的设计规则。
User{
i:id(1)
s:name(kraity)
}
可能看上去它些许像Java的类, 我们在 JSON
上增加了多类型支持即包名, 包名后面跟随着实例的别名或者变量名。
User
、i
、s
我们称这部分为 space
id
、name
我们称这部分为 alias
1
、kraity
我们称这部分为 value
花括号 {}
为一个实体 entity
, 小括号 ()
为一个基本属性 property
, 当然实体的属性还可以是实体。
space
对应包名或者类型, alias
对应变量名或者字段, value
自然是 space
的一个实例值。
设计理念
命名上, 我们当时选取 krait
的三个字母K
、A
、T
, 于是命名这套数据交换格式为KAT
。
我们在格式上追求清晰、体积小、拓展性强。
规定了基本space
的类型映射:
$ -> Object
i -> int
l -> long
f -> float
d -> double
b -> boolean
s -> String
I -> BigInteger
D -> BigDecimal
o -> byte
u -> short
B -> byte[] // base64
M -> Map // HashMap
L -> List // ArrayList
S -> Set // HashSet
A -> Array // Object[]
space
可以根据使用者自己而定, 比如自定义日期类型 Date:modified(Mon Feb 22 00:00:00 GMT 2022)
。还可以将上面规定的转为其他类型映射。
在实践项目开发中, space
可以是包名例如 plus.kat.entity.User
, 找到这个类的解释器然后自定义解析。
小伙伴可能会说, 怎么会记得住这多space
对应关系, 当然我们支持通配符 $
, 当时它仅能表示几种类型, 但是如果使用者绑定了实体Class
那么根据字段类型而解析。
User{
$:id(1)
$:name(kraity)
$:role()
$:blocked(false)
}
或者再简单一点
User{
:id(1)
:name(kraity)
:role()
:blocked(false)
}
解析机制
KAT
库反序列化时采用管道方式。 解析器 Codec
拟雷达 Radar
扫描方式将解析的数据一层一层的通过 Pipeline
传输到 Parser
, Parser
则根据 space
进行寻找类型解释器然后解析 value
, 如果没有解析器那么丢弃这个实体或者属性, 继续解析后面的。
KAT经过一年的发展, 最近支持了注释。
# this is a test entity
User{
l:uid(1)
s:name(kraity)
s:role(developer)
# status
b:blocked(0)
# extra data
M:contact{
I:age(6)
D:devote(1024)
}
}
最后, KAT库我们命名为KAT+, 同时注册了域名 kat.plus
, KAT+ 不仅支持解析 KAT
还支持解析 JSON
(KAT库是通用的, 只需实现 JSON
的 Codec
即可嵌入)。
开源共享
我们预计将在今年八月份开源KAT+, 以及完善更多的流行框架适配。
KAT+ Team Github
我们会开源在这个组织仓库里, 开源协议 Apache-2.0。
只管点赞就行了👍
哈哈😀
支持支持😁
感谢支持😜