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 将Bean转成成JSONObject的时候进行的特殊处理。 JsonValueProcessor 将Bean转换成JsonValue的时候对特殊的Java对象进行特殊的处理。 PropertyNameProcessor 修改Json的属性名称 DefaultDefaultValueProcessor 对指定的类型设置默认值

JsonBeanProcessor和JsonValueProcessor这两个Processor非常的像,都是在将Bean转换成Json的过程中发生作用。
JsonBeanProcessor是将Java对象转换成JSONObject,这个是强制要求的。比如你不能转换成一个JSON的值对象。
JsonValueProcessor是将Java对象转换成一个Object(可以是String,可以是其他的形式),比较灵活。

抽象类 描述 DefaultValueProcessorMatcher 待完善 JsonBeanProcessorMatcher 待完善 JsonValueProcessorMatcher 待完善 PropertyNameProcessorMatcher 待完善 实现类 描述 DefaultDefaultValueProcessor 待完善 JsDateJsonBeanProcessor 待完善 JsDateJsonValueProcessor 待完善 JsonVerifier 待完善

接下来我们就通过代码对各个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的处理器。 这里不进行赘述,都是默认的实现。

0 0
原创粉丝点击