解决json转换hibernate 结果集对象

本文探讨了在使用ext+ssh框架时,如何解决使用jsonlib转换hibernate的延迟加载对象时出现的报错问题。通过自定义JsonBeanProcessor,实现了将代理对象转化为普通对象的功能,从而成功解决了JSON转换问题。尽管此方法可能引入性能损耗,但提供了一种处理复杂对象转换的替代方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在使用ext+ssh框架过程中,当使用jsonlib 转换 hibernate的延迟加载对象时,会出现报错。为解决此处错误,我们可以参考网友网上给的解决思路,大概就是:
	public static JsonConfig getCommonConfig() {
		/*---- 做属性配置 start------*/
		JsonConfig conf = new JsonConfig();
		conf.registerJsonBeanProcessor(   
	            org.hibernate.proxy.HibernateProxy.class,   
	            new HibernateJsonBeanProcessor());   
	        conf.setJsonBeanProcessorMatcher(new HibernateJsonBeanProcessorMatcher());
		return conf;
	}

}

class HibernateJsonBeanProcessorMatcher extends JsonBeanProcessorMatcher {   
  
    @Override  
    public Object getMatch(Class target, Set set) {   
    if (target.getName().contains("$$EnhancerByCGLIB$$")) { 
        return org.hibernate.proxy.HibernateProxy.class;   
    }   
    return DEFAULT.getMatch(target, set);   
    }   
}

class HibernateJsonBeanProcessor implements JsonBeanProcessor {   
    public JSONObject processBean(Object obj, JsonConfig jsonConfig) {   
    	 LazyInitializer lazyInitializer = ((HibernateProxy)obj).getHibernateLazyInitializer(); 
         if(lazyInitializer.isUninitialized()) { 
         } 

    return new JSONObject();   
    }   
}


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

目前只能支持一级抓取。

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

/**
	 * 
	    * 功能描述:  解决hibernate 延迟加载对象问题
	    * @param dataList 数据集
	    * @param clazz 结果集内对象的class
	    * @return: void
	    * @author: lb
	    * @version: 2.0
	 */
	public static List listCrawl(List dataList,Class clazz){
		String ss="java.lang.String,java.util.Date,java.lang.Integer,java.lang.Long,int,float,long";
		String filterType="java.util.Map,java.util.HashMap,java.util.Set,java.util.HashSet";
		try{
		for(int i=0;i<dataList.size();i++){
			Object originalObj=dataList.get(i);//原始数据对象
			Method[] originalMethods= clazz.getDeclaredMethods();//原始数据对象的方法
			for(Method originalMethod:originalMethods){
				System.out.println("original MethodName:  "+originalMethod.getName());
				if(originalMethod.getName().contains("get")){
					System.out.println("getMethod returnType: "+originalMethod.getReturnType().getName());
					String returnType=originalMethod.getReturnType().getName();//get方法返回的对象类型
					if(!ss.contains(returnType)&&!filterType.contains(returnType)){//不是基本类型和Set Map等集合,即是二级对象
						Object proxyObjct=originalMethod.invoke(originalObj, null);//二级hibernate代理对象
						if(proxyObjct!=null){//二级代理对象是否为空
						Class proxyClass=proxyObjct.getClass();
						Method[] proxyMethods=proxyClass.getDeclaredMethods();
						
						Class tempClazz=Class.forName(returnType);//创建一个hibernate代理的原始二级对象
						Object tempObject=tempClazz.newInstance();//创建一个hibernate代理的原始二级对象
						
						for(Method proxyMethod:proxyMethods ){//
							if(ss.contains(proxyMethod.getReturnType().getName())){//只抓取hibernate代理的二级对象的基础数据
							if(proxyMethod.getName().contains("get")){
								Object returnValue=proxyMethod.invoke(proxyObjct, null);//
								System.out.println("proxy  returnValue:"+returnValue);
								String setMethod=proxyMethod.getName().replace("get", "set");
								System.out.println("setMethod name:"+setMethod);
								Method tempMethod=tempClazz.getDeclaredMethod(setMethod, proxyMethod.getReturnType());
								tempMethod.invoke(tempObject, returnValue);
							}
							}
						}
						Method originalMethod1=clazz.getDeclaredMethod(originalMethod.getName().replace("get", "set"), originalMethod.getReturnType());
						originalMethod1.invoke(originalObj, tempObject);//为原始对象重新装入一个非hibernate代理对象
						
						}
						
					}
					}
			}
		}
		}catch(Exception e){
			System.out.println("处理加载对象出现问题");
			e.printStackTrace();
		}
		
		return dataList;
	}


 

 我们通常对一个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 );

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值