There is a cycle in the hierarchy解决办法

2013/04/13 1641点热度 0人点赞 0条评论

相信大家做过JSON相关的东西对这个异常并不陌生,这个异常是由于JSONObject插件内部会无限拆解你传入的对象,直到没有可拆解为止,问题就在这,如果你传入的对象有外键关系,或者相互引用,那么内部就会死循环,也就会抛出这个异常
解决办法,我们先说一种网上通用的:过滤
不错,过滤肯定会解决该问题,过滤也有两种方法:

一种是通过

jsonConfig.setExcludes(new String[]{"dianYuanHeSuans"})

该方法接受一个数组,也就是你需要过滤的字段,很简单就能完成。
二种是通过

jsonConfig.setJsonPropertyFilter(new PropertyFilter() {

			@Override
			public boolean apply(Object source, String name, Object value) {
				if(name.equals("qualityChecks")){
					return true;
				}
				return false;
			}
		});

 

这种方式,其实和第一种差不多,达到同样的效果,也很简单。
接下来是我主要想说的,其实这两种方法,有种弊端
假如说我们一个User对象里有个属性是部门,引用的是Organzition这个对象,如果不做任何处理,调用JSONObject.fromObject方法同样会抛出异常,如果我们通过过滤把Organzition属性过滤了,那么在前台显示的时候,将看不到有关部门的任何信息,其实需要显示也不多,比如仅一个部门名字就可以,但是过滤掉什么都没有了,这个时候,很多同学会再建一个VO类来封装前台需要的属性,这无疑增加了工作量和代码的冗余,LZ正是被该问困扰了很久,所以给出个解决办法。

借用JSONObject里的JsonValueProcessor接口,我们自己实现该接口,代码如下:

/**
 * 解决JSONObject.fromObject抛出"There is a cycle in the hierarchy"异常导致死循环的解决办法
 * @author yxkong
 */
public class ObjectJsonValueProcessor implements JsonValueProcessor {

	/**
	 * 需要留下的字段数组
	 */
	private String[] properties;

	/**
	 * 需要做处理的复杂属性类型
	 */
	private Class<?> clazz;

	/**
	 * 构造方法,参数必须
	 * @param properties
	 * @param clazz
	 */
	public ObjectJsonValueProcessor(String[] properties,Class<?> clazz){
		this.properties = properties;
		this.clazz =clazz;
	}

	@Override
	public Object processArrayValue(Object value, JsonConfig jsonConfig) {
		return "";
	}

	@Override
	public Object processObjectValue(String key, Object value, JsonConfig jsonConfig) {
		PropertyDescriptor pd = null;
		Method method = null;
		StringBuffer json = new StringBuffer("{");
		try{
			for(int i=0;i<properties.length;i++){
				pd = new PropertyDescriptor(properties[i], clazz);
				method = pd.getReadMethod();
				String v = String.valueOf(method.invoke(value));
				json.append("'"+properties[i]+"':'"+v+"'");
				json.append(i != properties.length-1?",":"");
			}
			json.append("}");
		}catch (Exception e) {
			e.printStackTrace();
		}
		return JSONObject.fromObject(json.toString());
	}

}

 

在processObjectValue这个方法里重写,具体请看代码,另外在构造方法里我给出了两个参数,一个是需要留下来的属性名,通过数组传递,另一个是一个Class<?> type,也是相关上面说到例子中的Organzition.class,是用来在后面通过该class调用java反射机制获取属性值,在取到相关属值后组装成字符串,最后通过JSONObject.fromObject来输出,不这样输出会有问题,至于什么问题,有好奇心的同学自己试试

下面是调用方法:

jsonConfig.registerJsonValueProcessor(Organzition.class, 
       new ObjectJsonValueProcessor(new String[]{"orgName","orgId"},Organzition.class));

其中,Organzition.class是你要处理的属性类型

yxkong

这个人很懒,什么都没留下

文章评论

putlockers site watch movies online free Watch AlRawabi School for Girls 2021 Free Online Watch Snowpiercer 2020 Free Online Watch All of Us Are Dead 2022 Free Online