解决json转换hibernate 结果集对象

[java] view plain copy
 
  1. 在使用ext+ssh框架过程中,当使用jsonlib 转换 hibernate的延迟加载对象时,会出现报错。为解决此处错误,我们可以参考网友网上给的解决思路,大概就是:  
[java] view plain copy
 
  1.     public static JsonConfig getCommonConfig() {  
  2.         /*---- 做属性配置 start------*/  
  3.         JsonConfig conf = new JsonConfig();  
  4.         conf.registerJsonBeanProcessor(     
  5.                 org.hibernate.proxy.HibernateProxy.class,     
  6.                 new HibernateJsonBeanProcessor());     
  7.             conf.setJsonBeanProcessorMatcher(new HibernateJsonBeanProcessorMatcher());  
  8.         return conf;  
  9.     }  
  10.   
  11. }  
  12.   
  13. class HibernateJsonBeanProcessorMatcher extends JsonBeanProcessorMatcher {     
  14.     
  15.     @Override    
  16.     public Object getMatch(Class target, Set set) {     
  17.     if (target.getName().contains("
    EnhancerByCGLIB
    ")) {   
  18.         return org.hibernate.proxy.HibernateProxy.class;     
  19.     }     
  20.     return DEFAULT.getMatch(target, set);     
  21.     }     
  22. }  
  23.   
  24. class HibernateJsonBeanProcessor implements JsonBeanProcessor {     
  25.     public JSONObject processBean(Object obj, JsonConfig jsonConfig) {     
  26.          LazyInitializer lazyInitializer = ((HibernateProxy)obj).getHibernateLazyInitializer();   
  27.          if(lazyInitializer.isUninitialized()) {   
  28.          }   
  29.   
  30.     return new JSONObject();     
  31.     }     
  32. }  


在这种情况下,报错是解决了,但是输出的json对象串却是xxx:{}。
但是还需要这些数据,网上给出问题解决办法是使用vo之类的,个人感觉这样需要创建非长多的vo,使用繁琐。于是乎自己就琢磨使用反射,把hibernate的代理对象的数据取出来,转化为普通对应对象。结果还好,成功了。但是性能未进行测试,个人认为反射会带来性能的损失。现在代码贴出来,大家拍砖,分析哪方面需要改进。

目前只能支持一级抓取。

在使用ext+ssh框架过程中,当使用jsonlib 转换 hibernate的延迟加载对象时,会出现报错。为解决此处错误,我们可以参考网友网上给的解决思路,大概就是:

[java] view plain copy
 
  1. /** 
  2.      *  
  3.         * 功能描述:  解决hibernate 延迟加载对象问题 
  4.         * @param dataList 数据集 
  5.         * @param clazz 结果集内对象的class 
  6.         * @return: void 
  7.         * @author: lb 
  8.         * @version: 2.0 
  9.      */  
  10.     public static List listCrawl(List dataList,Class clazz){  
  11.         String ss="java.lang.String,java.util.Date,java.lang.Integer,java.lang.Long,int,float,long";  
  12.         String filterType="java.util.Map,java.util.HashMap,java.util.Set,java.util.HashSet";  
  13.         try{  
  14.         for(int i=0;i<dataList.size();i++){  
  15.             Object originalObj=dataList.get(i);//原始数据对象  
  16.             Method[] originalMethods= clazz.getDeclaredMethods();//原始数据对象的方法  
  17.             for(Method originalMethod:originalMethods){  
  18.                 System.out.println("original MethodName:  "+originalMethod.getName());  
  19.                 if(originalMethod.getName().contains("get")){  
  20.                     System.out.println("getMethod returnType: "+originalMethod.getReturnType().getName());  
  21.                     String returnType=originalMethod.getReturnType().getName();//get方法返回的对象类型  
  22.                     if(!ss.contains(returnType)&&!filterType.contains(returnType)){//不是基本类型和Set Map等集合,即是二级对象  
  23.                         Object proxyObjct=originalMethod.invoke(originalObj, null);//二级hibernate代理对象  
  24.                         if(proxyObjct!=null){//二级代理对象是否为空  
  25.                         Class proxyClass=proxyObjct.getClass();  
  26.                         Method[] proxyMethods=proxyClass.getDeclaredMethods();  
  27.                           
  28.                         Class tempClazz=Class.forName(returnType);//创建一个hibernate代理的原始二级对象  
  29.                         Object tempObject=tempClazz.newInstance();//创建一个hibernate代理的原始二级对象  
  30.                           
  31.                         for(Method proxyMethod:proxyMethods ){//  
  32.                             if(ss.contains(proxyMethod.getReturnType().getName())){//只抓取hibernate代理的二级对象的基础数据  
  33.                             if(proxyMethod.getName().contains("get")){  
  34.                                 Object returnValue=proxyMethod.invoke(proxyObjct, null);//  
  35.                                 System.out.println("proxy  returnValue:"+returnValue);  
  36.                                 String setMethod=proxyMethod.getName().replace("get", "set");  
  37.                                 System.out.println("setMethod name:"+setMethod);  
  38.                                 Method tempMethod=tempClazz.getDeclaredMethod(setMethod, proxyMethod.getReturnType());  
  39.                                 tempMethod.invoke(tempObject, returnValue);  
  40.                             }  
  41.                             }  
  42.                         }  
  43.                         Method originalMethod1=clazz.getDeclaredMethod(originalMethod.getName().replace("get", "set"), originalMethod.getReturnType());  
  44.                         originalMethod1.invoke(originalObj, tempObject);//为原始对象重新装入一个非hibernate代理对象  
  45.                           
  46.                         }  
  47.                           
  48.                     }  
  49.                     }  
  50.             }  
  51.         }  
  52.         }catch(Exception e){  
  53.             System.out.println("处理加载对象出现问题");  
  54.             e.printStackTrace();  
  55.         }  
  56.           
  57.         return dataList;  
  58.     }  


 

 我们通常对一个Json串和Java对象进行互转时,经常会有选择性的过滤掉一些属性值,而json-lib包中的JsonConfig为我们提供了这种功能,具体实现方法有以下几种。(1)建立JsonConfig实例,并配置属性排除列表,(2)用属性过滤器,(3)写一个自定义的JsonBeanProcessor.

1. 实现JSONString接口的方法

public class Person implements JSONString {  
    private String name;  
    private String lastname;  
    private Address address;  

     // getters & setters  

    public String toJSONString() {
                  return "{name:'"+name+"',lastname:'"+lastname+"'}";
    }
}


2.第二种方法通过jsonconfig实例,对包含和需要排除的属性进行方便的添加或删除

public class Person {  
private String name;  
private String lastname;  
private Address address;  

// getters & setters  
}  

JsonConfig jsonConfig = new JsonConfig();  
jsonConfig.setExclusions( new String[]{"address"});  
Person bean = new Person("jack","li");  
JSON json = JSONSerializer.toJSON(bean, jsonConfig); 

3. 使用propertyFilter可以允许同时对需要排除的属性和类进行控制,这种控制还可以是双向的,也可以应用到json字符串到java对象

public class Person {  
private String name;  
private String lastname;  
private Address address;  

// getters & setters  
}  

JsonConfig jsonConfig = new JsonConfig();  
jsonConfig.setJsonPropertyFilter( new PropertyFilter(){  

public boolean apply(Object source/* 属性的拥有者 */, String name /*属性名字*/, Object value/* 属性值 */ ){  
          // return true to skip name  
          return source instanceof Person && name.equals("address");  
}  
});  
Person bean = new Person("jack","li"); 
JSON json = JSONSerializer.toJSON( bean, jsonConfig ) 

4. 最后来看JsonBeanProcessor,这种方式和实现JsonString很类似,返回一个代表原来的domain类的合法JSONObject

public class Person {  
private String name;  
private String lastname;  
private Address address;  

// getters & setters  
}  

JsonConfig jsonConfig = new JsonConfig();  
jsonConfig.registerJsonBeanProcessor( Person.class, new JsonBeanProcessor(){  

public JSONObject processBean( Object bean, JsonConfig jsonConfig ){  
         if(!(bean instanceof Person)){  
                  return new JSONObject(true);  
         }  
         Person person = (Person) bean;  
         return new JSONObject() .element( "name", person.getName()) .element( "lastname", person.getLastname());  
}  
}); 

Person bean = new Person("jack","li"); 
JSON json = JSONSerializer.toJSON( bean, jsonConfig );

posted on 2017-07-10 15:10  alex5211314  阅读(576)  评论(0)    收藏  举报

导航