本系列之1: 简介
本系列之2: API服务开发
本系列之3: RSON序列化格式👈
本系列之4: RPC调度原理
本系列之5: NIO实现原理
本系列之6: 客户端动态代理原理
本系列之7: 注解处理器(APT)原理
本文介绍Rayson框架默认的序列化格式RSON。
RSON (Rayson Object Notation) 是 Rayson框架专用的一种轻量级的数据交换格式,它是一种语言中性、平台中性的结构化数据,被用于Rayson框架中作为默认的序列化格式。
正如本系列之1: 简介所述, Rayson框架的网络层通信协议采用标准的HTTP/1.1协议,而HTTP的协议格式是基于文本的,这样JSON作为一种流行的文本格式的数据交换格式,很适合作为Rayson的数据交换格式。不过,Rayson作为一个API服务器,性能是其设计的首要目标,JSON格式具有如下所述的缺点,因此并不适合作为Rayson的原生数据交换格式:
- 纯文本化的结构,解析起来速度慢。
- 文本化的数据占用较大的空间,导致传输速度变慢。
为了克服采用JSON带来的性能问题,Rayson设计了一种类似JSON的序列化格式RSON,它具有如下的特点,因此比JSON性能更高,更适合于作为API服务的数据交换格式。
- 基于字节流的数据格式,这样就比纯文本的JSON占用更小的空间。
- 结构化的数据格式,解释和编译起来比纯文本的JSON要快得多。
- 有更多的数据类型,更加适合无损失地序列化Java对象(Rayson采用JAVA语言定义API协议)。而JSON仅有少数几种数据类型(
null
,boolean
,string
,number
)。
RSON是Rayson框架的默认数据交换格式,这意味着:
- 框架底层的数据传输以及格式转换是基于RSON的。
- 为了兼容传统支持HTTP协议的客户端(例如浏览器、curl命令行等),Rayson也支持“application/x-www-form-urlencoded”、"application/json"等格式的通信数据。将来还会提供扩展其他格式的支持。
- Rayson通过HTTP请求头
Content-Type
来告诉服务器请求所使用的数据格式,例如RSON格式数据的请求头为Content-Type: application/rpc.rayson; charset=UTF-8
。
数据类型
RSON支持的数据类型如下表所示
Java对象类型 | Rson元素类型 | 类型值 | 备注 |
---|---|---|---|
null | RsonType.NULL | 0 | |
Boolean.TRUE | RsonType.TRUE | 1 | |
Boolean.FALSE | RsonType.FALSE | 2 | |
Byte | RsonType.BYTE | 3 | |
Short | RsonType.SHORT | 4 | |
Integer | RsonType.INT | 5 | |
Float | RsonType.FLOAT | 6 | |
Long | RsonType.LONG | 7 | |
Double | RsonType.DOUBLE | 8 | |
String , Enum | RsonType.STRING | 16 | 仅仅支持简单枚举 |
array list | RsonType.ARRAY | 32 | 数组元素可序列化 |
array list | RsonType.BIG_ARRAY | 33 | 元素个数大于127个 |
RsonSerializable | RsonType.OBJECT | 64 | 要求所有的字段均可以序列化 |
RsonSerializable | RsonType.BIG_OBJECT | 65 | 字段个数大于127个 |
byte array | RsonType.BYTE_ARRAY | 127 | |
java.util.Map | RsonType.OBJECT | With serializable parameterized type | |
java.util.List | RsonType.ARRAY | With serializable parameterized type |
表格中的RsonSerializable
是指实现了org.rayson.api.serial.RsonSerializable
接口的Java实体类。在RSON中,所有这类可序列化的复合对象(不包括java.util.Map
、java.util.List
)均需要实现这个接口。为了简单起见,下文对这种类型的RSON元素统一简称RSON对象。本文的RSON对象部分会对其展开讲述。
数据格式
RSON元素的通用数据格式如下所示:
0 1 2 3 4 5 6 7 ?
+-+-+-+-+-+-+-+-+--------------------+
| 类型值 | 数据内容 |
+-+-+-+-+-+-+-+-+--------------------+
其中,第一个字节为类型值,参考数据类型表。接下来零个或者多个字节为数据内容。其中,RsonType.NULL
,RsonType.TRUE
,RsonType.FALSE
的数据内容长度为零。其他元素类型的数据内容长度不为零。以下分别介绍余下的RSON元素类型的数据内容格式。
数据内容格式
- RsonType.BYTE
8 9 10 11 12 13 14 15
+--+--+--+--+--+--+--+--+
| 数据内容 |
+--+--+--+--+--+--+--+--+
- RsonType.SHORT
8 23
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| 数据内容 |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- RsonType.INT,RsonType.FLOAT
8 39
+--+--+--+--+--+...+--+--+--+--+--+
| 数据内容 |
+--+--+--+--+--+...+--+--+--+--+--+
- RsonType.LONG,RsonType.DOUBLE
8 71
+--+--+--+--+--+...+--+--+--+--+--+
| 数据内容 |
+--+--+--+--+--+...+--+--+--+--+--+
- RsonType.STRING
8 23 ?
+--+--+--+...+--+--+--+--------------------+
| 字符串长度 | 字符串字节数组 |
+--+--+--+...+--+--+--+--------------------+
- RsonType.ARRAY
8 9 10 11 12 13 14 15
+--+--+--+--+--+--+--+--+---------+---------+---------+
| 数组长度 |项目0数据 | ........|项目n数据 |
+--+--+--+--+--+--+--+--+---------+---------+---------+
其中,项目N的数据格式递归使用RSON的数据格式。
- RsonType.BIG_ARRAY
8 23
+--+--+--+....+--+--+--+---------+-------+---------+
| 数组长度 | 项目0数据 |.......|项目n数据 |
+--+--+--+....+--+--+--+---------+-------+---------+
- RsonType.OBJECT
8 9 10 11 12 13 14 15
+--+--+--+--+--+--+--+--+------+--------+-------+---+-------+---------+-------+
| 属性 | 属性名 | 属性名0 | 属性值 |...| 属性名 | 属性名n | 属性值 |
| 长度 | 0长度 | 字节数组 | 0数据 |...| n长度 | 字节数组 | n数据 |
+--+--+--+--+--+--+--+--+------+--------+-------+---+-------+---------+-------+
-
RsonType.BIG_OBJECT
格式与
RsonType.OBJECT
一致,除了属性长度是两个字节,从第8到第23个比特位。 -
RsonType.BYTE_ARRAY
8 23 ?
+--+--+--+...+--+--+--+--------------------+
| 字节数组长度 | 字节数组 |
+--+--+--+...+--+--+--+--------------------+
RSON对象
对象定义
一个RSON对象元素定义的例子
public class TestRsonObject implements RsonSerializable {
private final int i;
private final boolean b;
@SerializedName("s2")
private final String s;
private transient int t;
private byte[] bytes;
private String[] array;
private List<String> list;
private Map<String, String> map;
}
说明:
- 必须实现
org.rayson.api.serial.RsonSerializable
接口。 - 默认情况下RSON使用Java字段的名称来作为对应RSON对象属性的名称。也可以用注解
@org.rayson.api.annotation.SerializedName
来更改字段对应的RSON对象属性的名称。 - 使用Java关键字
transient
的字段不会被序列化为相应的RSON对象的属性。
序列化例子
下面是一个TestRsonObject
实例序列化的例子:
{
"b": false,
"array": [
"ab",
"cd",
"ef"
],
"bytes": "AgMF",
"i": 23,
"list": [
"item1",
"item2"
],
"map": {
"k1": "v1",
"k2": "v2"
},
"s2": "s"
}
为了简化显示,这里用类似JSON的字符串格式来代替实际的字节码格式。实际的RSON对象是使用结构化的字节流来序列化的,关于序列化的格式,请参考本文数据格式部分。
未完待续…