net.sf.json.JSONException: There is a cycle in the hierarchy!
这个问题说明,实体类对象包含另外一个实体类的对象,并且形成了循环引用。解决这个问题的方法可以通过设置jsonconfig来避免:
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setJsonPropertyFilter(new PropertyFilter() {
public boolean apply(Object obj, String name, Object value) {
if(value instanceof Set<?> || value instanceof TGGoodsEvaluate){ //这里是通过类名来过滤
return true;
}else{
return false;
}
}
});
jsonConfig.setJsonPropertyFilter(new PropertyFilter() {
public boolean apply(Object obj, String name, Object value) {
if(value instanceof Set<?> || value instanceof TGGoodsEvaluate){ //这里是通过类名来过滤
return true;
}else{
return false;
}
}
});
jsonConfig.setExcludes(new String[]{"addTime"}); //也可以通过变量名来过滤
net.sf.json.JSONException: java.lang.reflect.InvocationTargetException
相比上一个问题,这个问题更加隐晦一点,从栈信息里面看不到具体原因,通常有以下几个问题:
1、JSONArray array = JSONArray.fromObject(this.users.toArray()); //如果要转为json数组,那么需要将List先转为数组,然后再去进行json转换
2、因为bean里有Date字段,且从数据库里读出来的是java.sql.Date赋值给了java.util.Date,转化成JSONArray时出错;可以在从数据库读出Date 时直接写成:new java.util.Date(rs.getDate("date").getTime),这样就不会出错了;
如果是Hibernate生成的类,好像没遇到这种情况,如果遇到可以尝试以下方法:
json-lib有一个配置类JsonConfig
通过JsonConfig可以注册一个字段处理器
实现JsonValueProcessor接口即可
JsonConfig jsonConfig = new JsonConfig(); jsonConfig.registerJsonValueProcessor(java.util.Date.class,new JsonValueProcessor() { private SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd"); public Object processObjectValue(String key, Object value, JsonConfig jsonConfig) { return value == null ?"" : sd.format(value); } public Object processArrayValue(Object value, JsonConfig jsonConfig) { return null; } });
所以你最后应该把JsonConfig对象传入json操作方法
printWriter.write(JSONArray.fromObject(dutyList,jsonConfig).toString());
3、hibernate延时加载
这个问题也是被坑的最久的一个问题,主要是由于实体类还包含了另外一个实体类,并且出现了延迟加载导致的。当时错误栈信息也一直没有显示出这个错误,直到经测试发现,如果把内层包含的实体类new出来,在加到外层实体类里面,再去转json,可以正常进行,这才想到可能是延迟加载的问题,于是网上搜了一下得到以下解决方案:
JsonConfig cfg = new JsonConfig();
cfg.setExcludes(new String[]{"handler","hibernateLazyInitializer"});
最后在转json的时候把jsonconfig当做一个参数传入即可。