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(JSONObject.quote(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(JSONObject.quote(((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 java.util.*;
import org.json.JSONException; import org.json.JSONObject;
import com.aherp.framework.util.HiJSONUtil; import com.aherp.framework.util.JSONUtil;
public class Test ...{ public static void main(String[] args) throws JSONException ...{ CObj cObj = new CObj(); System.out.println("var jsonStr = " + JSONObject.quote(JSONUtil.toJSONString(cObj))+";"); } }
输出: var jsonStr = "{\"AList\":[\"hello\",false,{\"innerhm\":{\"gigi\":\"高兴\",\"sina\":7.4353999999999995651478457148186862468719482421875}},{}],\"ii\":7,\"oarray\":[352,false,\"kick\"],\"ss\":\"你好\",\"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; } } ;
|