Rayson API 框架分析系列之3:RSON序列化格式

本系列之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元素类型类型值备注
nullRsonType.NULL0
Boolean.TRUERsonType.TRUE1
Boolean.FALSERsonType.FALSE2
ByteRsonType.BYTE3
ShortRsonType.SHORT4
IntegerRsonType.INT5
FloatRsonType.FLOAT6
LongRsonType.LONG7
DoubleRsonType.DOUBLE8
String , EnumRsonType.STRING16仅仅支持简单枚举
array listRsonType.ARRAY32数组元素可序列化
array listRsonType.BIG_ARRAY33元素个数大于127个
RsonSerializableRsonType.OBJECT64要求所有的字段均可以序列化
RsonSerializableRsonType.BIG_OBJECT65字段个数大于127个
byte arrayRsonType.BYTE_ARRAY127
java.util.MapRsonType.OBJECTWith serializable parameterized type
java.util.ListRsonType.ARRAYWith serializable parameterized type

表格中的RsonSerializable是指实现了org.rayson.api.serial.RsonSerializable接口的Java实体类。在RSON中,所有这类可序列化的复合对象(不包括java.util.Mapjava.util.List )均需要实现这个接口。为了简单起见,下文对这种类型的RSON元素统一简称RSON对象。本文的RSON对象部分会对其展开讲述。

数据格式

RSON元素的通用数据格式如下所示:

    0 1 2 3 4 5 6 7          ?
   +-+-+-+-+-+-+-+-+--------------------+
   |     类型值     |      数据内容       |
   +-+-+-+-+-+-+-+-+--------------------+

其中,第一个字节为类型值,参考数据类型表。接下来零个或者多个字节为数据内容。其中,RsonType.NULLRsonType.TRUERsonType.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对象是使用结构化的字节流来序列化的,关于序列化的格式,请参考本文数据格式部分。

未完待续…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值