Json-lib 与 hibernate 共同使用的问题

[url]http://ericyou.iteye.com/blog/325246[/url]
hibernate使用CGLIB把POJO的domain对象动态代理,实现它的魔法,但是给JSON的序列化带来了麻烦,因为JSON无法对lazy的属性进行序列化。有以下的四个方法可以解决hibernate的序列化问题

domain类实现JSONString接口

建立JsonConfig实例,并配置属性排除列表

用属性过滤器
写一个自定义的JsonBeanProcessor
1. 实现JSONString接口是侵入性最强的方法

Java代码
public class Person implements JSONString {
private String name;
private String lastname;
private Address address;

// getters & setters

public String toJSONString() {
return "{name:'"+name+"',lastname:'"+lastname+"'}";
}
}

public class Person implements JSONString {
private String name;
private String lastname;
private Address address;

// getters & setters

public String toJSONString() {
return "{name:'"+name+"',lastname:'"+lastname+"'}";
}
}
2.第二种方法通过jsonconfig实例,对包含和需要排除的属性进行方便添加删除

Java代码
public class Person {
private String name;
private String lastname;
private Address address;

// getters & setters
}

JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setExclusions( new String[]{ "address" } );
Person bean = /* initialize */;
JSON json = JSONSerializer.toJSON( bean, jsonConfig );

public class Person {
private String name;
private String lastname;
private Address address;

// getters & setters
}

JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setExclusions( new String[]{ "address" } );
Person bean = /* initialize */;
JSON json = JSONSerializer.toJSON( bean, jsonConfig );
注意:这种方法不区分目标类,就是说如果有2个bean当中都存在“address”属性,那么采用这种方法,这两个bean中的address属性都将被排除

3. 使用propertyFilter可以允许同时对需要排除的属性和类进行控制,这种控制还可以是双向的,也可以应用到json字符串到java对象

Java代码
public class Person {
private String name;
private String lastname;
private Address address;

// getters & setters
}

JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setJsonPropertyFilter( new PropertyFilter(){
public boolean apply( Object source, String name, Object value ){
// return true to skip name
return source instanceof Person && name.equals("address");
}
});
Person bean = /* initialize */;
JSON json = JSONSerializer.toJSON( bean, jsonConfig )

public class Person {
private String name;
private String lastname;
private Address address;

// getters & setters
}

JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setJsonPropertyFilter( new PropertyFilter(){
public boolean apply( Object source, String name, Object value ){
// return true to skip name
return source instanceof Person && name.equals("address");
}
});
Person bean = /* initialize */;
JSON json = JSONSerializer.toJSON( bean, jsonConfig )
4. 最后来看JsonBeanProcessor,这种方式和实现JsonString很类似,返回一个代表原来的domain类的合法JSONOBJECT

Java代码
public class Person {
private String name;
private String lastname;
private Address address;

// getters & setters
}

JsonConfig jsonConfig = new JsonConfig();
jsonConfig.registerJsonBeanProcessor( Person.class,
new JsonBeanProcessor(){
public JSONObject processBean( Object bean, JsonConfig jsonConfig ){
if( !(bean instanceof Person) ){
return new JSONObject(true);
}
Person person = (Person) bean;
return new JSONObject()
.element( "name", person.getName() )
.element( "lastname", person.getLastname() );
}
});
Person bean = /* initialize */;
JSON json = JSONSerializer.toJSON( bean, jsonConfig );

public class Person {
private String name;
private String lastname;
private Address address;

// getters & setters
}

JsonConfig jsonConfig = new JsonConfig();
jsonConfig.registerJsonBeanProcessor( Person.class,
new JsonBeanProcessor(){
public JSONObject processBean( Object bean, JsonConfig jsonConfig ){
if( !(bean instanceof Person) ){
return new JSONObject(true);
}
Person person = (Person) bean;
return new JSONObject()
.element( "name", person.getName() )
.element( "lastname", person.getLastname() );
}
});
Person bean = /* initialize */;
JSON json = JSONSerializer.toJSON( bean, jsonConfig );
And it is here with JsonBeanProcessors where we encounter the second gotcha related to CGlib. As you noticed we registered the processor using Person as target class, but Hibernate returns a Proxy that is not exactly a Person but a subclass (if possible) of Person. The default matching algorithm used by Json-lib will try to match the exact class (using equals), meaning that your processor will not be called when you expect it to be,this is why JsonBeanProcessorMatcher was introduced, now you are be able to write the following code

<textarea class="java:nocontrols:nogutter" cols="80" rows="34" name="srccode">public class Person { private String name; private String lastname; private Address address; // getters & setters } JsonConfig jsonConfig = new JsonConfig(); jsonConfig.registerJsonBeanProcessor( Person.class, new JsonBeanProcessor(){ public JSONObject processBean( Object bean, JsonConfig jsonConfig ){ if( !(bean instanceof Person) ){ return new JSONObject(true); } Person person = (Person) bean; return new JSONObject() .element( "name", person.getName() ) .element( "lastname", person.getLastname() ); } }); jsonConfig.registerJsonBeanProcessorMatcher( new JsonBeanProcessorMatcher(){ public Object getMatch( Class target, Set/*<Class>*/ matches ){ for( Object match : matches ){ if( ((Class)match).isAssignableFrom(target) ){ return match; } } return null; } }); Person bean = /* initialize */; JSON json = JSONSerializer.toJSON( bean, jsonConfig );</textarea>

I hope these examples help dispel some doubts, in any case please feel free to drop by Json-lib's forum and mailing lists.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值