Json-lib的处理机制(1)--Processor接口
来源:互联网 发布:淘宝化妆品店铺起名 编辑:程序博客网 时间:2024/05/16 05:22
概述
JSON-lib是sourceforge上的开源项目,主要是对JSON格式进行处理,转换等操作的JavaAPI。
目前被广泛的应用到各种开源项目以及平台上,应用可谓非常广泛。接下来会有一系列的文章来对Json-lib的内部固有的处理机制进行举例实验,方便大家在以后使用的时候提供参考。
我们一般使用的场景就是将一个Java对象转换成JSON格式的数据,或者将一个JSON格式的数据转换成Java对象。
使用方法也非常简单:
集合形式的转换:
JSONArray.fromObject(list);
转换后
[{a:2,c:1}]
对象形式的转换:
JSONObject.fromObject(object);
转换后
{a:1,b:2}
但是实际上Json-lib在结构设计时,在转换过程中经过了Processor和Fitler处理,
通过对Processor和Filter进行扩展我们可以实现一些在特殊场景下的特殊处理。
Processor
路径在net.sf.json.processors
JsonBeanProcessor和JsonValueProcessor这两个Processor非常的像,都是在将Bean转换成Json的过程中发生作用。
JsonBeanProcessor是将Java对象转换成JSONObject,这个是强制要求的。比如你不能转换成一个JSON的值对象。
JsonValueProcessor是将Java对象转换成一个Object(可以是String,可以是其他的形式),比较灵活。
接下来我们就通过代码对各个Processor的功能进行详细的讲解:
测试的基础类
public class MyObject { public long num; public String name; public Date birthday; public Date firstDay; public MyObjectSon son; public String getName() { return name; } public void setName(String name) { this.name = name; } public long getNum() { return num; } public void setNum(long num) { this.num = num; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public Date getFirstDay() { return firstDay; } public void setFirstDay(Date firstDay) { this.firstDay = firstDay; } public MyObjectSon getSon() { return son; } public void setSon(MyObjectSon son) { this.son = son; }}
public class MyObjectSon{ public String name; public MyObjectSon(String n) { this.name=n; } public String getName() { return name; } public void setName(String name) { this.name = name; }}
JsonBeanProcessor
首先实验一下JsonBeanProcessor
/** * 针对Date.class 类型进行的特殊处理 * @author Administrator * */public class JsonBeanDateProcessor implements JsonBeanProcessor { /** * Bean转换成JSON对象是,默认的时期格式: * {"date":24,"day":4,"hours":16,"minutes":59,"month":10,"seconds":27,"time":1479977967668,"timezoneOffset":-480,"year":116} * 将复杂的日期格式转换成{"Value":"yyyy-MM-dd"}这样的形式。 */ @Override public JSONObject processBean(Object arg0, JsonConfig arg1) { if(arg0 instanceof Date) { String format = "yyyy-MM-dd"; SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.CHINA); String dateValue=sdf.format((Date)arg0); JSONObject obj=new JSONObject(); obj.element("Value", dateValue); return obj; } else if(arg0==null) { //测试一下,null的时候是否进入,就可以判断这个是根据属性类型,还是根据属性值类型进来的 //打印我闺女的生日 JSONObject obj=new JSONObject(); obj.element("Value", "2009-04-20"); return obj; } else { return JSONObject.fromObject(arg0); } } public static void main(String[] args) { MyObject obj=new MyObject(); obj.name="name11"; obj.birthday=new Date(); obj.num=100; System.out.println(JSONObject.fromObject(obj)); JsonConfig config = new JsonConfig(); //这里是注册了一个JsonBeanProcessor config.registerJsonBeanProcessor(Date.class, new JsonBeanDateProcessor()); JSONObject fromObject = JSONObject.fromObject(obj,config); System.out.println(fromObject.toString()); }}
执行后输出为:
{"birthday":{"date":24,"day":4,"hours":17,"minutes":53,"month":10,"seconds":22,"time":1479981202256,"timezoneOffset":-480,"year":116},"firstDay":null,"name":"name11","num":100,"son":null}{"birthday":{"Value":"2016-11-24"},"firstDay":null,"name":"name11","num":100,"son":null}
发现了么,firstDay还是null,证明进入processBean这个函数是根据属性值的类型进入的。
JsonBeanProcessor就是将Java对象转换成一个JSONObject对象。
但是问题来了,我不想转成一个JSONObject,我想直接转换成Value对象,怎么办?
用到JsonValueProcessor
JsonValueProcessor
/** * 针对于Date.class类型进行的特殊处理 * @author Administrator * */public class JsonValueDateProcessor implements JsonValueProcessor { /** * 这个方法不需要实现,因为我们传进来的数据都是Date.class,并不是Array类型的数据 */ @Override public Object processArrayValue(Object arg0, JsonConfig arg1) { return null; } @Override public Object processObjectValue(String arg0, Object arg1, JsonConfig arg2) { System.out.println("好奇arg0是什么,打出来看看="+arg0); if (arg1 instanceof Date) { String format = "yyyy-MM-dd"; SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.CHINA); return sdf.format(arg1); } else { //依然测试一下,是根据属性类型进入的还是根据属性值类型进入的, //如果为空,打印我闺女的生日 return arg1 == null ? "2009-04-20" : arg1.toString(); } } public static void main(String[] args) { //万能的MyObject MyObject obj=new MyObject(); obj.name="name11"; obj.birthday=new Date(); obj.num=100; System.out.println(JSONObject.fromObject(obj)); JsonConfig config = new JsonConfig(); //这里注册了一个JsonValueProcessor config.registerJsonValueProcessor(Date.class, new JsonValueDateProcessor()); JSONObject fromObject = JSONObject.fromObject(obj,config); System.out.println(fromObject.toString()); }}
控制台输出内容:
{"birthday":{"date":24,"day":4,"hours":17,"minutes":15,"month":10,"seconds":32,"time":1479978932491,"timezoneOffset":-480,"year":116},"firstDay":null,"name":"name11","num":100}好奇arg0是什么,打出来看看=birthday好奇arg0是什么,打出来看看=firstDay{"birthday":"2016-11-24","firstDay":"2009-04-20","name":"name11","num":100}
1:arg0就是属性的名称
2:调用这个是根据属性类型进入的,不是属性值。
两个Processor组合会是什么效果
为了让效果看的更清晰,我们在写一个JsonBeanProcessor
/** * * 修改Son的名字为Buth * @author Administrator * */public class JsonBeanSonProcessor implements JsonBeanProcessor { @Override public JSONObject processBean(Object arg0, JsonConfig arg1) { JSONObject obj=new JSONObject(); //修改所有的名字为buth obj.element("name", "buth"); return obj; }}
将3个processor都进行注册,注意注册的时候一定要注意一下注册的方法
config.registerJsonValueProcessor(Date.class, new JsonValueDateProcessor());config.registerJsonBeanProcessor(Date.class, new JsonBeanDateProcessor());config.registerJsonBeanProcessor(MyObjectSon.class, new JsonBeanSonProcessor());
看输出结果:
{"birthday":{"date":24,"day":4,"hours":17,"minutes":55,"month":10,"seconds":24,"time":1479981324649,"timezoneOffset":-480,"year":116},"firstDay":null,"name":"name11","num":100,"son":{"name":"jack"}}好奇arg0是什么,打出来看看=birthday好奇arg0是什么,打出来看看=firstDay{"birthday":"2016-11-24","firstDay":"2009-04-20","name":"name11","num":100,"son":{"name":"buth"}}
1.日期的格式都是:JsonValueDateProcessor改的。
2.MyObjectSon的格式是JsonBeanSonProcessor改的。
3.JsonBeanDateProcessor没有任何效果,执行了么?
为了调试我们在JsonBeanDateProcessor的函数中添加调试信息。
System.out.println(“execute json bean date”);但是输出依然没有变化,因此我们可以得出结论,对于同一个类型的处理器只执行一个。
PropertyNameProcessor
/** * 这个类是对MyObjectSon的属性名称进行修改的Processor * * @author Administrator * */public class PropertyNameSonProcessor implements PropertyNameProcessor { /** * @param arg0这个是传出的Class的名称。 * @param arg1这个是需要进行处理的属性名称 */ @SuppressWarnings("rawtypes") @Override public String processPropertyName(Class arg0, String arg1) { // 这里实际上是需要进行类的校验,忽略了,直接进行处理 if (arg1.equals("name")) { return "changeName"; } else { return arg1; } } public static void main(String[] args) { // 万能的MyObject MyObject obj = new MyObject(); obj.name = "name11"; obj.birthday = new Date(); obj.num = 100L; obj.son = new MyObjectSon("jack"); System.out.println(JSONObject.fromObject(obj)); JsonConfig config = new JsonConfig(); // 这里注册了一个JsonValueProcessor config.registerJsonValueProcessor(Date.class, new JsonValueDateProcessor()); config.registerJsonPropertyNameProcessor(MyObjectSon.class, new PropertyNameSonProcessor()); config.registerJsonBeanProcessor(Date.class, new JsonBeanDateProcessor()); JSONObject fromObject = JSONObject.fromObject(obj, config); System.out.println(fromObject.toString()); }}
控制台输出
{"birthday":{"date":24,"day":4,"hours":18,"minutes":39,"month":10,"seconds":45,"time":1479983985314,"timezoneOffset":-480,"year":116},"firstDay":null,"name":"name11","num":100,"son":{"name":"jack"}}好奇arg0是什么,打出来看看=birthday好奇arg0是什么,打出来看看=firstDay{"birthday":"2016-11-24","firstDay":"2009-04-20","name":"name11","num":100,"son":{"changeName":"jack"}}
属性名修改了
增加一个处理器:
config.registerJsonBeanProcessor(MyObjectSon.class, new JsonBeanSonProcessor());
输出为:
{"birthday":{"date":24,"day":4,"hours":18,"minutes":41,"month":10,"seconds":2,"time":1479984062712,"timezoneOffset":-480,"year":116},"firstDay":null,"name":"name11","num":100,"son":{"name":"jack"}}好奇arg0是什么,打出来看看=birthday好奇arg0是什么,打出来看看=firstDay{"birthday":"2016-11-24","firstDay":"2009-04-20","name":"name11","num":100,"son":{"name":"buth"}}
发现PropertyNameProcessor没有执行。好坑啊!!!属性名没有修改!
DefaultValueProcessor
/** * 给日期格式的数据设置默认值 * * @author Administrator * */public class DefaultValueDateProcessor implements DefaultValueProcessor { @SuppressWarnings("rawtypes") @Override public Object getDefaultValue(Class arg0) { // 默认返回儿子的生日 return "2013-11-12"; } public static void main(String[] args) { // 万能的MyObject MyObject obj = new MyObject(); obj.name = "name11"; obj.birthday = new Date(); obj.num = 100L; obj.son = new MyObjectSon("jack"); System.out.println(JSONObject.fromObject(obj)); JsonConfig config = new JsonConfig(); config.registerDefaultValueProcessor(Date.class, new DefaultValueDateProcessor()); JSONObject fromObject = JSONObject.fromObject(obj, config); System.out.println(fromObject.toString()); }}
输出如下:
{"birthday":{"date":25,"day":5,"hours":9,"minutes":14,"month":10,"seconds":48,"time":1480036488611,"timezoneOffset":-480,"year":116},"firstDay":null,"name":"name11","num":100,"son":{"name":"jack"}}{"birthday":{"date":25,"day":5,"hours":9,"minutes":14,"month":10,"seconds":48,"time":1480036488611,"timezoneOffset":-480,"year":116},"firstDay":"2013-11-12","name":"name11","num":100,"son":{"name":"jack"}}
发现null的日期类型被设置了默认值 “2013-11-12”。
增加其他processor试试。
config.registerJsonValueProcessor(Date.class, new JsonValueDateProcessor());
输出如下:
{"birthday":{"date":25,"day":5,"hours":9,"minutes":17,"month":10,"seconds":39,"time":1480036659048,"timezoneOffset":-480,"year":116},"firstDay":null,"name":"name11","num":100,"son":{"name":"jack"}}好奇arg0是什么,打出来看看=birthday好奇arg0是什么,打出来看看=firstDay{"birthday":"2016-11-25","firstDay":"2009-04-20","name":"name11","num":100,"son":{"name":"jack"}}
结果发现firstDay被JsonValueDateProcessor进行了修改,DefaultValueDateProcessor没有执行。
JsDateJsonBeanProcessor
JsDateJsonValueProcessor
这两个Processor实际上就是对java.utils.Date转换成JsDate的处理器。 这里不进行赘述,都是默认的实现。
- Json-lib的处理机制(1)--Processor接口
- Json-lib的处理机制(2)--ProcessorMatcher接口
- Json-lib的处理机制(3)--Filter接口
- 解决json-lib的一些序列化循环处理问题
- json-lib 日期处理类的一些用法
- Python接口对json串的处理
- Java 使用 json-lib 处理 JSON
- 使用json.org和json-lib来处理json字符串和java对象的转化
- 使用json-lib来处理数据(配合jquery)
- json-lib的json转换
- json-lib的使用
- JSON-Lib的使用
- json-lib的用法
- json lib的使用
- json-lib的使用
- json-lib的使用
- Json-lib的使用
- JSON-lib的使用
- linux下查看和添加PATH环境变量
- 接口和抽象类有什么区别
- netstat -i 和ifconfig -s的输出解释
- python selenium执行所有测试用例并生成报告
- linux解压不同后缀名文件的用法
- Json-lib的处理机制(1)--Processor接口
- 20161106#cs231n#1.最近邻分类器 Assignment1-KNN
- hadoop hdfs文件系统常用命令
- redis3.0 集群实战3 - java编程实战
- Linux_Linux命令_watch 用来指令输出的动态变化
- Java使用POI解析复杂Excel思维模式
- 实验二:外部中断与定时器/计数器中断实验
- hrbust 2249 开锁魔法II【概率dp】
- iOS 格式化输出符号