snack - Json 序列化应用与定制
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;
}
}