对象引用循环导致的 net.sf.json.JSONException: There is a cycle in the hierarchy

当使用json-lib在Java中把对象转换为JSON字符串时易产生的错误,主要的原因是出现了如下的情形:

model a里面包含了b,而model b里面又包含了a,这样造成了解析成对象的过程中的死循环,于是就报错了:

net.sf.json.JSONException: There is a cycle in the hierarchy!
at net.sf.json.util.CycleDetectionStrategy$StrictCycleDetectionStrategy.handleRepeatedReferenceAsObject(CycleDetectionStrategy.java:97)

如果还是需要保留这种关系,可以使用json-lib提供的JsonConfig把循环的属性在转换的过程中忽略掉:

JsonConfig config = new JsonConfig();
config.setExcludes(new String[]{“department”});
String json = JSONArray.fromObject(userList, config).toString();

当然,还有如下的方法可以实现属性的排除:

实现JSONString接口:(排除了desc)

public class User implements JSONString {
private String name;
private String password;
private String desc;

// getters & setters

public String toJSONString() {
return “{name:’”+name+”‘, password:’”+password+”‘}”;
}
}

设置JsonConfig的propertyFilter过滤属性:

public class User {
private String name;
private String password;
private String desc;
// …
}

JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setJsonPropertyFilter( new PropertyFilter(){
public boolean apply( Object source, String name, Object value ){
return source instanceof User && name.equals(“desc”);
}
});
User user = new User();
JSON json = JSONSerializer.toJSON( user, jsonConfig )

写一个自定义的JsonBeanProcessor方法:

public class User {
private String name;
private String password;
private String desc;
// …
}

JsonConfig jsonConfig = new JsonConfig();
jsonConfig.registerJsonBeanProcessor( User.class,
new JsonBeanProcessor(){
public JSONObject processBean( Object bean, JsonConfig jsonConfig ){
if( !(bean instanceof User) ){
return new JSONObject(true);
}
User user = (user) bean;
return new JSONObject()
.element( “name”, user.getName() )
.element( “password”, user.getPassword() );
}
});
User user = new User();
JSON json = JSONSerializer.toJSON( user, jsonConfig );

arthinking wechat
欢迎关注itzhai公众号