JSONSerializer的toJSON方法可以把参数指定的对象转换成一个JSON接口的对象,如果这个对象是一个String对象,那么这个方法还会校验这个String对象是否是一个合法的JSON字符串(即是否符合JavaScript的语法)。对于一般JavaBean(必须是标准的具有setter\getter的JavaBean)的转换就是按照属性值对的方式生成JS对象,缺省的情况下Map会转换成对象,而List和数组会转换为数组。
JSONSerializer的toJava方法可以把JSON接口的对象转换为JavaBean对象,缺省情况下,JSON接口的对象会被转换为net.sf.ezmorph.bean.MorphDynaBean对象,所有基本类型(基本类型包装类)、数组和String类型的属性都会被准确的装换,而其他类型(如Map等)都会被缺省的转换为net.sf.ezmorph.bean.MorphDynaBean对象。
以上是使用JSONSerializer的缺省转换函数(一个参数)进行转换的结果,如果使用两个参数的转换函数(第二个参数为JsonConfig对象),则会按照JsonConfig的配置进行转换。toJSON转换时的配置:
setJsonPropertyFilter属性过滤,用于处理那些属性被过滤掉而不被转化换为JSON,嵌套引用的Bean的属性也可以被过滤。如下:
/* 使用属性过滤器 */
myBeanJc.setJsonPropertyFilter(new PropertyFilter() {
@Override
public boolean apply(Object o, String n, Object v) {
if (o instanceof MyBean && n.equals("beanMap")) {
MyBean mb = (MyBean) o;
if (mb.getBeanMap().keySet().isEmpty())
return true;
} else if (o instanceof MyInnerBean && n.equals("attrMap")) {
Map<String, String> m = (Map<String, String>) v;
if (m.keySet().isEmpty())
return true;
} else
;
return false;
}
});
这个例子使用了匿名类的方式实现了一个自定义的属性过滤器,其实就是覆盖apply方法,这个方法的返回值决定是否把此属性过滤掉(true表示过滤掉此属性而不转化到JSON中)。json-lib本身提供一些实现了PropertyFilter的属性过滤器类供我们使用,如AndPropertyFilter, CompositePropertyFilter, FalsePropertyFilter, MappingPropertyFilter, NotPropertyFilter, OrPropertyFilter, TruePropertyFilter等,有兴趣的话可以逐个试验。
registerJsonBeanProcessor注册JsonBeanProcessor,使用JsonBeanProcessor处理bean对象到JSON接口对象的转换,它给我们提供了自定义的bean到JSON的转换的接口,通过注册自定义的JsonBeanProcessor我们可以按照自己的想法把bean转化成我们想要的样子。如下:
/* 使用JsonBeanProcessor处理bean对象到json对象的转换 */
myBeanJc.registerJsonBeanProcessor(MyInnerBean.class,
new JsonBeanProcessor() {
@Override
public JSONObject processBean(Object o, JsonConfig jc) {
return JSONObject
.fromObject("{title : 'I am an inner bean!'}");
}
});
这个例子就给MyInnerBean注册了一个自定义的JsonBeanProcessor,使用匿名类的方式实现了processBean方法,processBean方法返回的JSON对象就是在进行bean到JSON转化时MyInnerBean对象转化成的JSON对象。
setJsonBeanProcessorMatcher可以设置用于匹配JsonBeanProcessor的自定义的匹配器JsonBeanProcessorMatcher,通过实现JsonBeanProcessorMatcher的getMatch方法(这个方法有两个参数,第一个是需要匹配的对象的Class对象,第二个参数是所有注册了JsonBeanProcessor的Class对象的集合),返回一个Calss对象,转换器会用以返回的Class对象注册的JsonBeanProcessor处理这个类的转换。如下:
/* 设置处理过程的注册类匹配器 */
myBeanJc
.setJsonBeanProcessorMatcher(new JsonBeanProcessorMatcher() {
@Override
public Object getMatch(Class c, Set s) {
if (c.equals(MyInnerBean.class))
return innerClzz.class;
return c;
}
});
这个例子使用匿名类实现了一个自定义的JsonBeanProcessorMatcher,覆盖了getMatch方法,它表示在bean到JSON的转化过程中,如果我们要处理的类是MyInnerBean类,则返回innerClzz类,这时就会使用innerClzz注册的JsonBeanProcessor来处理这个MyInnerBean,如果我们没有为innerClzz注册JsonBeanProcessor,则使用缺省的转化过程处理(属性值对的方式)。
registerJsonValueProcessor注册JsonValueProcessor,使用JsonValueProcessor处理Bean对象的属性值的转换,这里是为指定的数据类型注册JsonValueProcessor。如下:
/* 使用JsonValueProcessor处理Bean对象的属性值的转换 */
myBeanJc.registerJsonValueProcessor(Double.class,
new JsonValueProcessor() {
@Override
public Object processArrayValue(Object arg0,
JsonConfig arg1) {
return null;
}
@Override
public Object processObjectValue(String k, Object v,
JsonConfig arg2) {
if (k.equals("dblVal"))
return Double.valueOf(v.toString())
.doubleValue()
* 100 + "%";
else
return v;
}
});
这个例子就是为双精度浮点型注册了一个JsonValueProcessor,需要我们覆盖两个方法,从名称就能明白它们是分别处理数组和对象中的指定数据类型的方法。在这里我们把属性dblVal的双精度浮点值转化为表示百分比的字符串,对于其他的双精度浮点值不做处理。
注册处理过程的方法都有其对应的反注册(unregisterXxProcessor)方法,同时还提供了查找这些处理过程的方法(findXxProcessor)。
setExcludes设置不作转换的属性名称,getExcludes可以返回设置的属性名称字符串数组,而getMergedExcludes可以返回所有不做转换的属性集合,包括setExcludes设置的属性名称。
setJavaIdentifierTransformer设置使用何种Java标识符的转换器,没太看懂,JavaIdentifierTransformer倒是挺好理解,可是这个转换功能如何使用,在什么时候使用呢?
setArrayMode设置数组的转换模式,也不会用。
setRootClass设置根对象目标类,也就是从JSON接口对象转换为bean时得到的对象的Java类,如果不设置的话,就转换为MorphDynaBean。
setNewBeanInstanceStrategy用于设置对象实例化时使用的策略,缺省的是使用Class的newInstance方法。从JSON接口对象转换成JavaBean对象时首先应用该策略,然后才会用JSON接口对象的内容为实例赋值。如下:
/* 设置对象实例化策略 */
myBeanJc.setNewBeanInstanceStrategy(new NewBeanInstanceStrategy() {
@Override
public Object newInstance(Class c, JSONObject jo)
throws InstantiationException, IllegalAccessException {
Object o;
if (c.equals(MyInnerBean.class)) {
String t = "Recovered " + jo.get("title");
jo.put("title", t);
o = new MyInnerBean();
}else
o = c.newInstance();
return o;
}
});
这个例子中, 使用匿名类的方式覆盖newInstance方法,如果是MyInnerBean类则使用无参构造函数实例化对象,其他情况下使用缺省的实例化方式。因为从JSON接口对象转换成JavaBean对象时首先应用该策略,然后才会用JSON接口对象的内容为实例赋值,所以在这里为实例化对象赋值是没有意义的,如果想改变最后的bean的属性值,可以通过修改JSON对象的属性值来实现。
setClassMap应该是用于JSON和XML转换的,有待进一步研究。
此外还有其他相对简单的转换过程配置选项的功能,比较容易理解和使用,类似于开关量。如:disableEventTriggering() ,enableEventTriggering()等等。