最近用ssh写了个小项目,但是在用hibernate实现双向关联的时候,然后在将其转换为json字符串的时候出现异常。异常的大致意思就是转换的时候出现了死循环。然后,自己只想到了一种比较笨的解决方案,然后在百度了这个问题的解决方案,总共有三种解决办法,如下:
相关准备:
在这里呢,这两个类是一对多的关系,Customer是一的那方,LinkMan是多的那方。
这句代码意思,将数据库中的所用cutomer的信息都查询出来,这个呢,linkMan的相关信息也会查询出来。
List<Customer> list = customerService.findAll();
一,循环遍历将产生死循环的置为null
这是我能想到的方法,因为这种解决方法,很普通,所以我就只说一说它的思路,我们自己在创建一个list2的集合,然后在遍历list数组,把list中的数据全部赋值给list2就可以了,在遍历的工程中,我们需要将Customer中的linkMans这个属性置为null就可以了,或者将LinkMan中的customer这个属性置为null就可以了。
二选一,但是我推荐后者,这是因为,如果我们将Customer中的linkMans这个属性置为null后,如果我们前台需要使用的LinkMan的相关信息,那么这种解决方法就不适合,所以当我们将LinkMan中的customer这个属性置为null的时候,我们在把list转换为json给前台,那么前台可以得到LinkMan的相关信息。
二,设置过滤器
这种解决方法是我通过百度才找到的,亲测有效,由于本人编程技术不强,所以没有查看过源码,所以不知道这种解决方法在源码里面是怎样产生效果的,在这里我只是知道这样做可以解决问题,但不知道这样做在底层是如何实现的。
List<Customer> list = customerService.findAll();
JsonConfig jsonConfig = new JsonConfig();
//一定要加这句代码,我百度了好久,然后看了很多博文,发现他们很多都是用来这种方法,但是好像很多都没这句代码
//我没有加这句代码的时候一直没有成功,加上就成功了。
jsonConfig.setExcludes(new String[]{"handler","hibernateLazyInitializer"});//这一行是为了防止hibernate延迟加载造成的异常而设置的。
jsonConfig.setJsonPropertyFilter(new PropertyFilter() {
//下面来说说这相关参数的大致意思:
//Object obj,的意思是我们需要过滤的这个属性的类型,比如我们需要过滤到类型为String,的就可以用这个。eg:obj instanceof String
//String name,这个属性的名字。
//Object value,这个好像与值有关但是我不明白这个的作用是什么。
//返回true,表示过滤掉。
//返回false,表示不用过滤掉的。
@Override
public boolean apply(Object obj, String name, Object value) {
if(name.equals("linkMans")) {
return true;
}
return false;
}
});
JSONArray jsonArray = JSONArray.fromObject(list,jsonConfig);
在这里我们如果过滤掉的是linkMans的化,会引发在一的解决方案中的问题,所以在这里最好的方案是过滤掉,customer,所以相关变化如下:
将name.equals(“linkMans”)变为name.equals(“customer”)就可以了。
三,取消循环策略
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setIgnoreDefaultExcludes(false); //设置默认忽略
jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);//设置循环策略为忽略 解决json最头疼的问题 死循环
jsonConfig.setExcludes(new String[] {"customer","handler","hibernateLazyInitializer"});//此处是亮点,只要将所需忽略字段加到数组中即可
JSONArray jsonArray = JSONArray.fromObject(list, jsonConfig);
注意在这句代码:
jsonConfig.setExcludes(new String[] {"customer","handler","hibernateLazyInitializer"});
一定不能省略"handler","hibernateLazyInitializer"这个东西,不然可能转化会失败。
最后:
希望自己以后能通过源码分析出以上解决方案实现的原因,加油!!!