Solon v3.6.0

snack - Json 序列化应用与定制

</> markdown

1、序列化参考

基础操作

User user = new User();
ONode.ofBean(user).toBean(User.class); //可以作为 bean 转换使用
ONode.ofBean(user).toJson();

ONode.ofJson("{}").toBean(User.class);
ONode.ofJson("[{},{}]").toBean((new ArrayList<User>(){}).getClass());

快捷方式

String json = ONode.serialize(user);
User user = ONode.deserialize(json, User.class);

2、序列化定制面板 Options

Options 提供有序列化特性、时间格式、时区、地区、类加载器、对象编码器、对象解码器、对象工厂等可选定制。其中:

  • 对象编码器(ObjectEncoder,ObjectPatternEncoder),负责把 Jav a 对象转为 ONode 实例
  • 对象解码器(ObjectDecoder,ObjectPatternDecoder),负责把 ONode 实例转为 Java 对象
  • 对象工厂(ObjectFactory,ObjectPatternFactory),负责实例化 Java 类。顺道可以处理类型安全问题

对象编码器和对象解码器,一般成对出现。比如,实现 Class 对象的序列化(其实已经内置了)。

public class OptionsDemo {
    public static void main(String[] args) {
        Options options = Options.of();

        //编码:使用类的名字作为数据
        options.addEncoder(Class.class, ((ctx, value, target) ->  {
            return target.setValue(value.getName());
        }));

        //解码:把字符串作为类名加载(成为类)
        options.addDecoder(Class.class, (ctx, node) -> {
            return ctx.getOptions().loadClass(node.getString());
        });

        //测试:序列化
        Map<String,Class<?>> data = new HashMap<>();
        data.put("list", ArrayList.class);

        String json = ONode.serialize(data, options);
        System.out.println(json);  // {"list":"java.util.ArrayList"}
        assert "{\"list\":\"java.util.ArrayList\"}".equals(json);

        //测试:反序列化
        data = ONode.deserialize(json, new TypeRef<Map<String,Class<?>>>() {}, options);
        System.out.println(data.get("list")); // class java.util.ArrayList
        assert ArrayList.class.equals(data.get("list"));
    }
}

使用特性(Feature)控制细节:

public class FeatureDemo {
    public static void main(String[] args) {
        Options options = Options.of().addFeature(Feature.Write_BigNumbersAsString);

        Map<String, Object> data = new HashMap<>();
        data.put("a", 1);
        data.put("b", 2L);
        data.put("c", 3F);
        data.put("d", 4D);

        //序列化
        String json = ONode.serialize(data, options);
        System.out.println(json); //{"a":1,"b":"2","c":3.0,"d":"4.0"} //b 和 d 变成字符串了

        json = ONode.serialize(data, Feature.Write_NumberType); //也可直接使用特性
        System.out.println(json); //{"a":1,"b":2L,"c":3.0F,"d":4.0D} //带了数字类型(有些框架不支持)

        //反序列化:带数字类型符号的,可以还原数字类型
        Map map = ONode.deserialize(json, Map.class);
        assert map.get("b") instanceof Long;
    }
}