您的位置:首页 > 移动开发 > Objective-C

自己编写的一个Json工具类,实现了反射将整个Object转换为Json对象的功能,支持Hibernate的延迟加载对象

2008-05-23 09:10 1281 查看
由于Json自己的String转换有问题,无法正确的转换中文为uxxxx的字符,因此改用DWR包内的JavascriptUtil处理 String类型。可以直接引用,还可以拆离出来,因为仅是一个转换工具类,跟DWR的没有依赖关系。这样就可以采用ISO-8859-1编码来传递所有 UNICODE了。

代码:


package com.aherp.framework.util;




import java.lang.reflect.Array;


import java.lang.reflect.Method;


import java.util.Collection;


import java.util.Iterator;


import java.util.Map;




import org.json.JSONArray;


import org.json.JSONException;


import org.json.JSONObject;


import org.json.JSONString;






/** *//**


* JSON工具类,反射的方式转换整个对象


* @author Jim Wu


*


*/




public class JSONUtil ...{




private static JSONUtil instance = null;






public JSONUtil()...{}






/** *//**


* 代理类时做的检查.返回应该检查的对象.


* @param bean


* @return


*/




protected Object proxyCheck(Object bean)...{


return bean;


}






static public String toJSONString(Object obj) throws JSONException...{


return toJSONString(obj, false);


}






static public String toJSONString(Object obj, boolean useClassConvert) throws JSONException...{


if(instance == null)


instance = new JSONUtil();


return instance.getJSONObject(obj, useClassConvert).toString();


}






private String getJSONArray(Object arrayObj, boolean useClassConvert) throws JSONException...{




if(arrayObj == null)


return "null";




arrayObj = proxyCheck(arrayObj);




JSONArray jSONArray = new JSONArray();




if(arrayObj instanceof Collection)...{


Iterator iterator = ((Collection)arrayObj).iterator();




while(iterator.hasNext())...{


Object rowObj = iterator.next();


if(rowObj == null)


jSONArray.put(new JSONStringObject(null));


else if(rowObj.getClass().isArray() || rowObj instanceof Collection)


jSONArray.put(getJSONArray(rowObj, useClassConvert));


else


jSONArray.put(getJSONObject(rowObj, useClassConvert));


}


}




if(arrayObj.getClass().isArray())...{


int arrayLength = Array.getLength(arrayObj);




for(int i = 0; i < arrayLength; i ++)...{


Object rowObj = Array.get(arrayObj, i);


if(rowObj == null)


jSONArray.put(new JSONStringObject(null));


else if(rowObj.getClass().isArray() || rowObj instanceof Collection)


jSONArray.put(getJSONArray(rowObj, useClassConvert));


else


jSONArray.put(getJSONObject(rowObj, useClassConvert));


}


}


return jSONArray.toString();


}






JSONStringObject getJSONObject(Object value, boolean useClassConvert) throws JSONException...{




//处理原始类型




if (value == null) ...{


return new JSONStringObject("null");


}


value = proxyCheck(value);




if (value instanceof JSONString) ...{


Object o;




try ...{


o = ((JSONString)value).toJSONString();




} catch (Exception e) ...{


throw new JSONException(e);


}


throw new JSONException("Bad value from toJSONString: " + o);


}




if (value instanceof Number) ...{


return new JSONStringObject(JSONObject.numberToString((Number) value));


}


if (value instanceof Boolean || value instanceof JSONObject ||




value instanceof JSONArray) ...{


return new JSONStringObject(value.toString());


}


if (value instanceof String)


return new JSONStringObject('"' + JavascriptUtil.escapeJavaScript(value.toString()) + '"');




if (value instanceof Map) ...{




JSONObject jSONObject = new JSONObject();




Iterator iterator = ((Map)value).keySet().iterator();




while(iterator.hasNext())...{


String key = iterator.next().toString();


Object valueObj = ((Map)value).get(key);


jSONObject.put(key, getJSONObject(valueObj, useClassConvert));


}


return new JSONStringObject(jSONObject.toString());


}




//class


if(value instanceof Class)


return new JSONStringObject(JavascriptUtil.escapeJavaScript(((Class)value).getSimpleName()));




//数组




if (value instanceof Collection || value.getClass().isArray()) ...{


return new JSONStringObject(getJSONArray(proxyCheck(value), useClassConvert));


}




return reflectObject(value, useClassConvert);


}//value.equals(null)






private JSONStringObject reflectObject(Object bean, boolean useClassConvert)...{


JSONObject jSONObject = new JSONObject();




Class klass = bean.getClass();


Method[] methods = klass.getMethods();




for (int i = 0; i < methods.length; i += 1) ...{




try ...{


Method method = methods[i];


String name = method.getName();


String key = "";




if (name.startsWith("get")) ...{


key = name.substring(3);




} else if (name.startsWith("is")) ...{


key = name.substring(2);


}


if (key.length() > 0 &&


Character.isUpperCase(key.charAt(0)) &&




method.getParameterTypes().length == 0) ...{




if (key.length() == 1) ...{


key = key.toLowerCase();




} else if (!Character.isUpperCase(key.charAt(1))) ...{


key = key.substring(0, 1).toLowerCase() +


key.substring(1);


}


Object elementObj = method.invoke(bean, null);


if(!useClassConvert && elementObj instanceof Class)


continue;




jSONObject.put(key, getJSONObject(elementObj, useClassConvert));


}




} catch (Exception e) ...{




/**//* forget about it */


}


}


return new JSONStringObject(jSONObject.toString());


}


}




package com.aherp.framework.util;




import org.json.JSONString;






public class JSONStringObject implements JSONString ...{




private String jsonString = null;






public JSONStringObject(String jsonString)...{


this.jsonString = jsonString;


}




@Override




public String toString() ...{


return jsonString;


}






public String toJSONString() ...{


return jsonString;


}


}



调用测试程序


import java.util.ArrayList;


import java.util.HashMap;


import java.util.List;








public class AObj ...{


private int ii = 7;


private boolean bb = true;


private String ss = "你好";


private List aList = new ArrayList();






public AObj()...{


aList.add("hello");


aList.add(false);


aList.add(new BObj());


aList.add(new HashMap());


}






public boolean isBb() ...{


return bb;


}




public void setBb(boolean bb) ...{


this.bb = bb;


}




public int getIi() ...{


return ii;


}




public void setIi(int ii) ...{


this.ii = ii;


}




public String getSs() ...{


return ss;


}




public void setSs(String ss) ...{


this.ss = ss;


}




public List getAList() ...{


return aList;


}




public void setAList(List list) ...{


aList = list;


}


}




import java.math.BigDecimal;


import java.util.HashMap;








public class BObj ...{




private HashMap innerhm = new HashMap();






public BObj()...{


double dd = 7.4354;


innerhm.put("gigi", "高兴");


innerhm.put("sina", new BigDecimal(dd));


}






public HashMap getInnerhm() ...{


return innerhm;


}






public void setInnerhm(HashMap innerhm) ...{


this.innerhm = innerhm;


}


}








public class CObj extends AObj...{






private Object[] oarray = new Object[]...{352, false, "kick"};






public Object[] getOarray() ...{


return oarray;


}






public void setOarray(Object[] oarray) ...{


this.oarray = oarray;


}


}




import org.json.JSONException;




import com.aherp.framework.util.JSONUtil;






public class Test ...{




public static void main(String[] args) throws JSONException ...{


CObj cObj = new CObj();


System.out.println(JSONUtil.toJSONString(cObj));


}


}





输出:
{"AList":["hello",false,{"innerhm":{"gigi":"/u9AD8/u5174","sina":7.4353999999999995651478457148186862468719482421875}},{}],"ii":7,"oarray":[352,false,"kick"],"ss":"/u4F60/u597D","bb":true}

如 果需要支持Hibernate,那么必须弄清其机制。Hibernate采用CGLIB对VO对象进行字节码增加,实际机制就是使用一个原类型的 proxy子类,其子类实现了HibernateProxy接口。其接口有一个isUninitialized的判断方法,用来判断该代理类是否已经初始 化(还记得在事务外使用延迟加载的对象会抛no Session的错误吗,正是由于实际使用的对象已经变成原来类的子类proxy了)。而对于one-to-many映射时,很难判断对象只加载一次,因 此为了避免递归调用死循环,忽略了Hibernate的one-to-many集合的递归反射。其原理和many-to-one一样,也是一个子类化的 proxy,具有PersistentSet的接口。

因此,支持Hibernate的JSONUtil如下:


package com.aherp.framework.util;




import org.hibernate.collection.PersistentSet;


import org.hibernate.proxy.HibernateProxy;


import org.hibernate.proxy.LazyInitializer;


import org.json.JSONException;






/**//**


* 支持Hibernate的JSONUtil.


* 自动检测是否已经代理加载,如果未加载,则将对象仅加载为OID


* @author Jim Wu


*


*/




public class HiJSONUtil extends JSONUtil ...{




private static HiJSONUtil instance = null;






static public String toJSONString(Object obj) throws JSONException...{


return toJSONString(obj, false);


}






static public String toJSONString(Object obj, boolean useClassConvert) throws JSONException...{


if(instance == null)


instance = new HiJSONUtil();


return instance.getJSONObject(obj, useClassConvert).toString();


}




@Override




protected Object proxyCheck(Object bean) ...{


System.out.println("Class is ..." + bean.getClass().getName());




if(bean instanceof HibernateProxy)...{


LazyInitializer lazyInitializer = ((HibernateProxy)bean).getHibernateLazyInitializer();




if(lazyInitializer.isUninitialized())...{


System.out.println(">>>>>lazyInitializer.getIdentifier()="+ lazyInitializer.getIdentifier());


return lazyInitializer.getIdentifier();


}


}




if(bean instanceof PersistentSet)...{




return new String[]...{}; //忽略hibernate one-to-many


}


return bean;


}


}


;

但是这样还是有个问题,当one-to-one具备双向映射关系时,会陷入调用递归死循环。因此避免这样的情况
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐