自己编写的一个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具备双向映射关系时,会陷入调用递归死循环。因此避免这样的情况
代码:
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具备双向映射关系时,会陷入调用递归死循环。因此避免这样的情况
相关文章推荐
- 自己编写的一个Json工具类,实现了反射将整个Object转换为Json对象的功能,支持Hibernate的延迟加载对象
- 自己编写的一个Json工具类,实现了反射将整个Object转换为Json对象的功能,支持Hibernate的延迟加载对象[修订081217]
- Json工具类,实现了反射将整个Object转换为Json对象的功能,支持Hibernate的延迟加
- json数据与JAVA数据的转换 jsonJavaBean.netApache 自己编写了一个工具类,处理页面提交json格式数据到后台,再进行处理成JAVA对象数据 1、DTO:Data T
- 利用Java反射实现普通对象到JSONObject的转换
- json解决hibernate中级联对象延迟加载有关问题
- 用自己的思路编写一个$.extend()/Object.assign()对象合并函数
- C#实现JSON和对象之间互相转换功能示例
- 一个自己编写的xml和JAVA对象之间的转换工具,xml和对象轻松转换(simple-xml2object)
- 使用java反射实现对象工厂以及工具类的编写
- fastjson序列化hibernate代理和延迟加载对象出现no session异常的解决办法
- 自己写的一个Java Bean转换为HashMap及ArrayList容器的功能类,支持Hibernate
- writeObject可以写n个,但是readObject()却只能读一次,你做一下测试。 如果你需要序列化好几个类的话,建议你用json;或者自己写两个方法,一个是将对象转换为字符串,一个是将字符串
- //1、有一个字符串开头或结尾含有n个空格(” abcdefgdddd ”),欲去掉前后空格,返回一个新字符串。 //要求1:请自己定义一个接口(函数),并实现功能;70分 //要求2:编写
- jQuery实现form表单序列化转换为json对象功能示例
- 利用泛型和反射对Java对象集合转换成Json的工具类
- 尝试自己写一个工具类实现UGUI的按钮功能
- json解决hibernate中级联对象延迟加载问题net.sf.json.JSONException: org....
- Jquery将一个object对象转换成json字符串
- JSONArray,JSONObject工具类实现Json,bean,map,list等的转换