Json-lib的处理机制(1)--Processor接口

概述

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
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值