常见的Json转换工具有google的gson和阿里的fastgson。目前主流策略:POJO序列化成JSON字符串用Gson库,JSON字符串反序列化为POJO,用fastJson库。
Netty中JSON编码和解码原理
JSON格式仅仅是字符串的一种组织形式。所以,传输JSON的所用到的协议与传输普通文本所使用的协议没有什么不同。下面使用常用的Head-Content协议来介绍一下JSON传输。
编码
先使用StringEncoder编码器(Netty内置)将JSON字符串编码成二进制字节数组。然后,使用LengthFieldPrepender编码器(Netty内置)将二进制字节数组编码成Head-Content二进制数据包。
LengthFieldPrepender编码器的作用:在数据包的前面加上内容的二进制字节数组的长度。这个编码器和LengthFieldBasedFrameDecoder解码器是天生的一对,常常配套使用。这组“天仙配”属于Netty所提供的一组非常重要的编码器和解码器,常常用于Head-Content数据包的传输。
解码
Head-Content数据包的解码过程如图8-3所示,具体如下:先使用LengthFieldBasedFrameDecoder(Netty内置的自定义长度数据包解码器)解码Head-Content二进制数据包,解码出Content字段的二进制内容。然后,使用StringDecoder字符串解码器(Netty内置的解码器)将二进制内容解码成JSON字符串。最后,使用JsonMsgDecoder解码器(一个自定义解码器)将JSON字符串解码成POJO对象。
Netty使用StringEncoder编码器对String进行转换。当然,String类有自带的编解码方法,String类的getBytes()方法使用StringCoding类的encode()方法,本质上是将char[]数组转为byte[],因为char占两个字节,byte占一个字节,转换得到的数组长度会不一样。
示例
这里使用String的getBytes()方法进行序列化和逆序列化(底层是StringCoding类的encode和decode方法),代码示例如下
1 @Data 2 public class SimplePOJO implements Serializable { 3 String field1; 4 String field2; 5 public SimplePOJO(String s1, String s2) { 6 field1 = s1; 7 field2 = s2; 8 } 9 // fastjson逆序列化时要求对象必须要有一个默认的构造函数 10 public SimplePOJO(){} 11 } 12 public static void main(String[] args) throws IOException, ClassNotFoundException { 13 String jsonStr = JSON.toJSONString(student); 14 FileOutputStream fos = new FileOutputStream("C:\\Users\\user\\Desktop\\student.dat"); 15 // 将字符串编码为字节数组时要和解码时使用相同字符集格式 16 fos.write(jsonStr.getBytes("utf-8")); 17 fos.close(); 18 19 FileInputStream fis = new FileInputStream( "C:\\Users\\user\\Desktop\\student.dat"); 20 byte[] bytes = new byte[fis.available()]; 21 fis.read(bytes); 22 String deJsonStr = new String(bytes,"utf-8"); 23 SimplePOJO deStudent = JSON.parseObject(jsonStr, SimplePOJO.class); 24 }
我们用文本编辑器打开保存的中间文件student.dat看看。