概述
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的处理器。 这里不进行赘述,都是默认的实现。