保存到桌面加入收藏设为首页
java开发
当前位置:首页 > java开发

Tomjson-安度博客

时间:2019-02-04 14:52:57   作者:   来源:   阅读:53   评论:0
内容摘要:  Tomjson,一个'短小精悍'的 json 剖析库,tomjson使用Java语言编写,主要作用是把Java工具(JavaBean)序列化为json名堂字符串,将json名堂字符串序列化为相对应的Java工具(JavaBean)。项目地址:https://g......
  •   Tomjson,一个'短小精悍'的 json 剖析库,tomjson使用Java语言编写,主要作用是把Java工具(JavaBean)序列化为json名堂字符串,将json名堂字符串序列化为相对应的Java工具(JavaBean)。项目地址:https://github.com/luoxn28/tomjson。关于JSON更多信息请点击JSON-百度百科。

      一些有名的json序列化相关的项目有gjson、fastjson和jackjson,其中LZ使用过fastjson,另外两个没有使用过,看过一点fastjson的源码,由此发生了写一个json序列化相关库的想法,也就是现在的Tomjson。通过学习和使用Tomjson,LZ大致相识了Java类与json字符串之间的应该如何转换及代码实现。Tomjson是基于Java反射来举行序列化事情的,并不像fastjson那样可以通过ASM框架来指针每种类型生成对应的序列化类;Tomjson架构简朴,明确起来较其他json序列化库相对容易一些。

      Tomjson在序列化时体现了“专人专事”的思想,好比如果是String类型的数据,则交给StringSerializer类来序列化;如果是Integer类型的数据,则交给IntegerSerializer类来处置惩罚。Tomjson在反序列化处置惩罚也是类似的,这样整体逻辑较量清晰。

    json.png

    1、如何使用

      下载源码导入到工程中,新建TestMain类,代码如下:

    package com.luoxn28.test;import com.luoxn28.tomjson.TomJson;import com.luoxn28.tomjson.deserializer.Jsonobject;import java.util.ArrayList;import java.util.Arrays;import java.util.Map;/** * TestMain - 测试 */public class TestMain { public static void main(String[] args) { Person person = new Person(&#39;luxon28&#39; 23); person.setMoney(13.14); person.setDog(new Dog(&#39;gay&#39;)); person.setDogs(new ArrayList<Dog>(Arrays.asList(new Dog(&#39;gay1&#39;) new Dog(&#39;gar2&#39;)))); System.out.println(&#39;----- object序列化为json -----&#39;); String jsonString = TomJson.toJsonString(person); System.out.println(jsonString); System.out.println(&#39;----- json序列化为object,未提供object类型 -----&#39;); Jsonobject jsonobject = TomJson.parseobject(jsonString); for (Map.Entry<String object> entry : jsonobject.entrySet()) { System.out.print(entry.getKey() + &#39;: &#39; + entry.getValue() + &#39; | &#39;); } System.out.println(); System.out.println(&#39;----- json序列化为object,提供object类型 -----&#39;); Person jsonPerson = TomJson.parseobject(jsonString Person.class); System.out.println(jsonPerson); }}

    输出效果为:

    其中Person类和Dog类代码如下:

    /** * Person - 测试类 */public class Person { // ---------------------------------- Instance Variable private String name; private int age; private double money; private Dog dog; private List<Dog> dogs = new ArrayList<>(); // ---------------------------------- Constructors public Person() { } public Person(String name int age) { this.name = name; this.age = age; } // ---------------------------------- Public Methods public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } public List<Dog> getDogs() { return dogs; } public void setDogs(List<Dog> dogs) { this.dogs = dogs; } @Override public String toString() { return &#39;Person{&#39; + &#39;name=&#39;&#39; + name + &#39;&#39;&#39; + &#39; age=&#39; + age + &#39; money=&#39; + money + &#39; dog=&#39; + dog + &#39; dogs=&#39; + dogs + &#39;}&#39;; }}
    /** * Dog - 测试类 */public class Dog { // ---------------------------------- Instance Variable private String name; // ---------------------------------- Constructors public Dog() { } public Dog(String name) { this.name = name; } // ---------------------------------- Public Methods public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return &#39;Dog{&#39; + &#39;name=&#39;&#39; + name + &#39;&#39;&#39; + &#39;}&#39;; }}

    2、Tomjson架构

    2.1 Tomjson特点

    小巧:源码中就包罗4个包,deserializer包主要是一些JavaBean序列化为json字符串相关的类,serializer包主要是一些json字符串反序列化为JavaBean的类,util中有一个工具类TinyUtil.java,test是一些测试类。 精悍:在小型类的序列化话速度上照旧很快的 :) 。

    2.2 Tomjson序列化思想

      当Java类序列化为json字符串时,通过反射获取对应Class类的各个数据域,然后获取数据域名称和值,通过写入到SerializerBuffer(封装了StringBuffer的一个类)中。主要代码如下:

    // objectSerializer - object序列化类@Overridepublic void write(String name object object SerializerBuffer buffer) { try { // name为null体现是Root object if (name == null) { Class clazz = object.getClass(); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { String key = field.getName(); PropertyDescriptor descriptor = new PropertyDescriptor(key clazz); Method method = descriptor.getReadMethod(); object value = method.invoke(object); JsonSerializer write = config.getobject(value.getClass()); write.write(key value buffer); } } else { SerializerBuffer subBuffer = new SerializerBuffer(); write(null object subBuffer); buffer.append(object &#39;&#39;&#39; + name + &#39;&#39;:&#39; + subBuffer.toString()); } } catch (Exception e) { e.printStackTrace(); }}

      当json字符串反序列化为Java类时,首先获取json字符串中的各个token,token也就是json字符串中的键值对,类似于&#39;name&#39;:&#39;luxon28&#39;这种结构,获取token的要领如下,调用一次就可以获取到在同一条理下(也可以说在同一个类的条理)的所有token。

    /** * 获取tokens 也就是以&#39;&#39;为脱离符把text分成多个token * 注意:获取text中处于最上层的各个token */private static List<String> getTokens(String text) { List<String> tokens = new ArrayList<>(); Stack<Character> flag = new Stack<>(); text = text.trim(); text = TinyUtil.trimBrace(text); for (int i = 0 length = text.length() tokenIndex = 0; i < length; i++) { char c = text.charAt(i); if (c == &#39;{&#39; || c == &#39;[&#39;) { flag.push(c); } else if (c == &#39;}&#39; || c == &#39;]&#39;) { char tmp = flag.pop(); if (!TinyUtil.flagOk(tmp c)) { System.out.println(&#39;json string format error&#39;); return new ArrayList<>(); } } if (c == &#39;&#39; && flag.size() == 0) { tokens.add(text.substring(tokenIndex i)); tokenIndex = i + 1; } else if (i == length - 1 && flag.size() == 0) { tokens.add(text.substring(tokenIndex length)); } } return tokens;}

      获取到token后,就可以单独分析每一个token了,可以把token看成一个键值对,也就是&#39;name&#39;:&#39;luxon28&#39;这种结构。如果值是由&#39;&#39;所困绕的,则该值就是String类型的,如果该值没有被&#39;&#39;所困绕,则体现是数值类型的,再凭据详细数值类型判断是Integer照旧Double类型。相关代码如下:

    /** * 剖析json字符串,将效果存放到clazz实例中 */public static <T> T parseobject(String text Class<T> clazz) { List<String> tokens = getTokens(text); Jsonobject jsonobject = new Jsonobject(); for (String token : tokens) { if (TinyUtil.isBeanKeyValue(token)) { parse(token jsonobject.keyValue); } else if (TinyUtil.isJsonBean(token)) { String key = TinyUtil.getJsonKey(token); String valueStr = TinyUtil.getJsonValue(token); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { String name = field.getName(); if (name.equals(key)) { String type = field.getGenericType().toString(); String className = type.substring(type.indexOf(&#39; &#39;) + 1 type.length()); Class subClazz = null; try { subClazz = Class.forName(className); } catch (ClassNotFoundException e) { e.printStackTrace(); // break for (Field field : fields) break; } try { object subobject = subClazz.newInstance(); subobject = parseobject(valueStr subClazz); jsonobject.keyValue.put(key subobject); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } else if (TinyUtil.isJsonCollectionBean(token)) { String key = TinyUtil.getJsonKey(token); String valueStr = TinyUtil.getJsonValue(token); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { String name = field.getName(); if (name.equals(key)) { String type = field.getGenericType().toString(); String valueClass = type.substring(type.indexOf(&#39;<&#39;) + 1 type.indexOf(&#39;>&#39;)); List list = new ArrayList<>(); List<String> beans = getTokens(&#39;{&#39; + TinyUtil.trimSquare(valueStr) + &#39;}&#39;); for (String bean : beans) { Class subClazz = null; try { subClazz = Class.forName(valueClass); } catch (ClassNotFoundException e) { e.printStackTrace(); break; } object subobject = parseobject(bean subClazz); list.add(subobject); } jsonobject.keyValue.put(TinyUtil.getJsonKey(token) list); } } } else { System.out.println(&#39;I don&#39;t know how to do it :(&#39;); } } T object = null; try { object = clazz.newInstance(); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { String name = field.getName(); PropertyDescriptor descriptor = new PropertyDescriptor(name clazz); Method method = descriptor.getWriteMethod(); if (jsonobject.keyValue.containsKey(name)) { object arg = jsonobject.keyValue.get(name); method.invoke(object arg); } } } catch (Exception e) { e.printStackTrace(); } finally { return object; }}

    2.3 Tomjson源码分析

      Tomjson的口点是TomJson类,TomJson的toJsonString()要领是将Java类序列化为json字符串,parseobject()要领是将json字符串反序列化为Java类,其返回Jsonobject类型或者Java类类型,如果给parseobject()要领通报类类型的话。

      SerializerContext和DeserializerContext是tomjson的配置类,其中SerializerContext存放的是关于Java类序列化为json字符串的配置,也就是Class类型与json序列化类映射关系,DeserializerContext存放的是关于json字符串反序列化为Java类的配置,也就是Class类型与json反序列化类映射关系。

    TomJson类

    public class TomJson { // serializer配置类 private static SerializerContext config = SerializerContext.instance(); // ---------------------------------- Public Methods /** * object转换为json字符串 */ public static String toJsonString(object object) { SerializerBuffer buffer = new SerializerBuffer(); JsonSerializer write = config.getobject(object.getClass()); write.write(null object buffer); return buffer.toString(); } /** * json字符串转换为Jsonobject */ public static Jsonobject parseobject(String text) { return Jsonobject.parseobject(text); } /** * json字符串转换为指定的object */ public static <T> T parseobject(String text Class<T> clazz) { return Jsonobject.parseobject(text clazz); }}

    SerializerContext类

    public class SerializerContext { // 存放Class类型与json序列化类映射关系 private static Map<Class JsonSerializer> config = null; // objectSerializer序列化类 private static objectSerializer objectSerializer = null; // Collection序列化类 private static CollectionSerializer collectionSerializer = null; static { config = new HashMap<Class JsonSerializer>(); config.put(String.class new StringSerializer()); config.put(Boolean.class new BooleanSerializer()); config.put(Integer.class new IntegerSerializer()); config.put(Long.class new LongSerializer()); config.put(Double.class new DoubleSerializer()); } // ...}

    DeserializerContext类

    public class DeserializerContext { private static DeserializerContext context = new DeserializerContext(); // 存放Class类型与json反序列化类映射关系 private static Map<Class JsonDeserializer> config = null; static { config = new HashMap<Class JsonDeserializer>(); config.put(String.class new StringDeserializer()); config.put(Integer.class new IntegerDeserializer()); config.put(Long.class new LongDeserializer()); config.put(Double.class new DoubleDeserializer()); } // ...}

    参考:

      1、项目地址:https://github.com/luoxn28/tomjson。

      2、fastjson:https://github.com/alibaba/fastjson


最近更新

精彩推荐

阅读排行

本站所有站内信息仅供娱乐参考,不作任何商业用途,不以营利为目的,专注分享快乐,欢迎收藏本站!
所有信息均来自:百度一下 (威尼斯人官网)