第一种方法:
项目当中我希望把一个对象方便的封装成JSON对象,当然需要导入相关Jar 包 json-lib-2.2.2-jdk15.jar 与
commons-beanutils-1.7.0.jar
下面生成Json对象,使用fromObject()方法将user对象格式化成Json格式,如下面代码:
JSONObject json = new JSONObject().fromObject(user)
当我重启运行后,出现下面的错误
net.sf.json.JSONException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.ares.pojo.Member.blacklists, no session or session was closed
这种错误是因为 Hibernate 对象映射后延迟加载错误,好吧,我们把lazy=flase就OK了.可惜我使用的注解的形式,所以我得把 fetch = FetchType.EAGER 换成 fetch = FetchType.LAZY 以为成功了,可是还是出错了,异常如下:net.sf.json.JSONException: There is a cycle in the hierarchy!
好吧,上面的异常出现那你就不得不看看你映射后的实体当中是不是有对象的集合,这里我将我的实体(member)对象给大家看一下,如下图:
实体当中有四个集合,如下:
private Set<Prepaidlog> prepaidlogsForOperateid = new HashSet<Prepaidlog>(0);
private Set<Shortmsg> shortmsgs = new HashSet<Shortmsg>(0);
private Set<Prepaidlog> prepaidlogsForOperatedid = new HashSet<Prepaidlog>(0);
private Set<Blacklist> blacklists = new HashSet<Blacklist>(0);
当json-lib反序列化中会进行双向转换,从而形成死循环,会报一个json-lib的经典异常:net.sf.json.JSONException: There is a cycle in the hierarchy!
也就是说主外键自身关联的是个死循环,那怎么才能不让他出现这种情况呢,应该有个配置的参数后者终止循环的地方吧,查看发
现,jsonConfig,呵呵,config应该是配置参数吧,参看JsonConfig看见巨多的属性,有点晕PropertyFilter
,不提了,看了老半天,发现了一个属性PropertyFilter,PropertyFilter 是一个interface,代码如下:
public interface PropertyFilter
{
public abstract boolean apply(Object obj, String s, Object obj1);
}
也就是说我可以通过这个方法过滤掉集合里的相应属性,只要让它返回true就可过滤掉,……,有点悬……我们重写一下这个方法:
JsonConfig cfg = new JsonConfig();
cfg.setJsonPropertyFilter(new PropertyFilter()
{
public boolean apply(Object source, String name, Object value) {
if(name.equals("prepaidlogsForOperateid ")||name.equals("shortmsgs ")||name.equals("prepaidlogsForOperatedid ")||name.equals("blacklists ")) {
return true;
} else {
return false;
}
}
});
将hibernate产生的实体bean中的prepaidlogsForOperateid 和shortmsgs 和 prepaidlogsForOperatedid 还有 blacklists 过滤掉就OK了!
然后调用JSONObject jsonObject = JSONObject.fromObject(member, config);将数据转换成Json对象.
第二种方法:
第二种方法使用的是Google的Gson 当然导入相关Jar包:gson-2.1.jar
如果没有主外键自身关联的死循环那,直接可以使用
Gson gson = new Gson();
gson.toJson(member);
上面的方法就是把对象封装成Json对象.
可是我的情况就不一样了,我的操作如下:
因为采用的是注解开发,以所我在我的实体当中要显示的属性要设置为@Expose,当实体的属性设置成@Expose注释的属性将不会被序列化,如我下图:
然后如下使用就可以了
Gson gson=new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
gson.toJson(member);
不足之处请大家指点与拍砖,谢谢!