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;
    }
}
;

 

Json工具类,实现了反射将整个Object转换为Json对象的功能,支持Hibernate的延迟加的更多相关文章

  1. JSON工具类的构建(后端版本)

    前言 在前后端交互的选择上,之前一直采用的是模板引擎(因为我只负责后端). 而这次的一个算是作业吧,前后端都是我,所以就研究了一下JSON交互在java web的应用(主要是前端). 优缺点 前后端耦 ...

  2. 用jackson封装的JSON工具类

    package hjp.smart4j.framework.util; import com.fasterxml.jackson.databind.ObjectMapper; import org.s ...

  3. Code片段 : .properties属性文件操作工具类 & JSON工具类

    摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “贵专” — 泥瓦匠 一.java.util.Properties API & 案例 j ...

  4. Json工具类 - JsonUtils.java

    Json工具类,提供Json与对象之间的转换. 源码如下:(点击下载 - JsonUtils.java . gson-2.2.4.jar ) import java.lang.reflect.Type ...

  5. Java json工具类,jackson工具类,ObjectMapper工具类

    Java json工具类,jackson工具类,ObjectMapper工具类 >>>>>>>>>>>>>>> ...

  6. Spring统一返回Json工具类,带分页信息

    前言: 项目做前后端分离时,我们会经常提供Json数据给前端,如果有一个统一的Json格式返回工具类,那么将大大提高开发效率和减低沟通成本. 此Json响应工具类,支持带分页信息,支持泛型,支持Htt ...

  7. 强大的Java Json工具类

    转自: https://blog.csdn.net/u014676619/article/details/49624165 import java.io.BufferedReader; import ...

  8. HttpClientUntils工具类的使用测试及注意事项(包括我改进的工具类和Controller端的注意事项【附 Json 工具类】)

    HttpClient工具类(我改过): package com.taotao.httpclient; import java.io.IOException; import java.net.URI; ...

  9. json工具类(三)——net包

    package com.ruoyi.common.utils.json; import java.util.List; import java.util.Map; import net.sf.json ...

随机推荐

  1. Linux命令行下创建纳入版本控制下的新目录

    [root@ok 资料库]# svn mkdir test A test [root@ok 资料库]# svn ci -m "mkdir test" Adding 资料库/test ...

  2. 使yum保留下载的rpm包

    [root@14LN yum]# egrep 'cachedir|keepcache' /etc/yum.conf #cachedir=/var/cache/yum/$basearch/$releas ...

  3. C#的面向对象特性之封装

    在C#语言中,共有五种访问修饰符:public.private.protected.internal.protected internal. public 公有访问.不受任何限制.private 私有 ...

  4. ***PHP类型转换实例:$this->input->get()返回的结果是字符串类型(数字字符串转数字)

    一个GET的REST API,请求有三个参数,且都是数字 用$this->input->get()方法获取后的结果是字符串,需要转换为数字:如果没有获取到数据,则会返回false,需要用e ...

  5. Unity3D入门之GUI基础以及常用GUI控件使用(2)

    1.GUI基础 (1)GUI部分是每帧擦除重绘的,只应该在OnGUI中绘制GUI,按钮:GUILayout.Button(“Hello”); 只读标签:GUILayout.Label() (2)修改控 ...

  6. [原]C# Winform 文件编码批量转换工具

    在发布产品程序包时,往往需要对程序文件进行编码检查,写了一个可以批量修改文件编码格式的辅助工具,希望对有同样需求的童鞋有帮助. 1.程序界面: 2.核心代码: /// <summary> ...

  7. 动态链接库(dll)简介(转)

    DLL 是 Dynamic Link Library 的缩写,译为“动态链接库”.DLL也是一个被编译过的二进制程序,可以被其他程序调用,但与 exe 不同,DLL不能独立运行,必须由其他程序调用载入 ...

  8. SQLServer2008 绑定默认值

    默认值或绑定:(newid())值:2E014A19-7AF5-471E-866C-DC5D6DFE59A5 (dateadd(day,(1),getdate()))值: 2014-07-31 20: ...

  9. vs2010如何生成EXE文件如何更改EXE程序图标

    vs2010如何生成EXE文件 F5启动调试后,进入下面路径查找: 我的文档\Visual Studio 2010\Projects\项目名称\项目名称\bin\Debug 如何更改EXE程序图标 其 ...

  10. hdu 1181 变形课

    变形课 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submis ...