分享

8.4 JSON转换器 - 接口实现 - AJava

 banpaia 2010-08-18

8.4  接口实现

8.4.1  json2Obj 实现

根据需求分析中JSON 到Java对象的数据转换规则,json2Obj 方法的输入参数jsonStr,可能为以下几种情况:

(1)单值,如“abcd”。

(2)值序列,如 [1, 2, 5, 9]。

(3)名值对,如 { x : 10, y : 25}。

(4)嵌套,如 {leftUpper: [20,50], rightDown: [200, 450]}。

因此,json2Obj函数,首先要将JSON 字符串分解为一系列属性。这里属性的含义,可以代表一个最基本的名值对,也可以代表单值。

属性分解完毕后,接着就要分析目标对象的类型。目标对象可能为如下情况之一:

(1)Java内置类型:直接将JSON串分解后的属性转换为Java内置类型即可;

(2)数组:对每个属性递归调用json2Obj,返回的对象设置到数组的相应元素位置上;

(3)集合类型:对每个属性递归调用json2Obj,返回的对象添加到相应的集合中;

(4)Map:对每个属性递归调用json2Obj,返回的对象作为Value,属性名作为Key,添加到Map中;

(5)用户自定义对象:用反射技术解析对象的各个属性,对每个JSON串解析出的各个属性,调用json2Obj,将返回的对象设置到Java对象相应的属性上。

核心代码实现如下:

         /**

          * 将Json 串转换为Java对象

          * @param jsonStr 待转换的Json串,可以是内置类型、数组或者对象,

          *                                  也可以是上述三种的任意组合

          * @param cls 目标Java对象的类

          * @return 返回转换后的Java对象,可能是内置类型、数组、集合类型或者对象

          * @exception 如果转换过程出现异常,统一抛出GeneralException 异常

          */

         public static <T> T json2Obj(String jsonStr, Class<T> cls) {

                  // 1. 如果是内置类型,则直接进行数据类型转换即可

                  String objTypeName = cls.getName();

                  int objType = DataType.getDataType(objTypeName);

                  if (DataType.isSimpleType(objType)) {   // 简单类型

                           jsonStr = jsonStr.trim();

                           jsonStr = delQuote(jsonStr);   // 去掉引号

                           return (T)DataType.toType(jsonStr, DataType.DT_String, objType);

                  }

                 

                  // 2. 解析jsonStr, 切出各个属性

                  // 2.1 合并成单行

                  jsonStr = jsonStr.replace("\n", "");

                  //jsonStr = jsonStr.replace("\t", "");

                  jsonStr = jsonStr.trim();

                  // 2.2 分解出各个属性

                  List<JsonProp> propList = splitProperties(jsonStr);

                 

                  // 3. 创建目标对象

                  Object obj = null;

                  switch (objType) {

                  case DataType.DT_Array:       // 数组的创建需要知道数组元素的类型和数组长度,因此后续再创建

                           break;

                  case DataType.DT_List:

                           obj = ClassReflector.newInstance("java.util.ArrayList");

                           break;

                  case DataType.DT_Set:

                           obj = ClassReflector.newInstance("java.util.HashSet");

                           break;

                  case DataType.DT_Map:

                           obj = ClassReflector.newInstance("java.util.Hashtable");

                           break;

                  default:

                           obj = ClassReflector.newInstance(cls);

                  }

                 

                  // 4. 处理对象的场景

                  if (objType == DataType.DT_UserDefine) {     // 对象

                           ClassReflector reflector = new ClassReflector(obj);

                            // 逐个属性向obj 赋值

                           for (JsonProp p : propList) {

                                     String propTypeName = reflector.getPropertyType(p.propName);

                                     Object propObj = json2Obj(p.jsonPropValue, propTypeName);

                                     reflector.setPropertyValue(p.propName, propObj);

                           }

                           return (T)obj;

                  }

                 

                  // 5. 处理数组/集合的场景

                  // 5.1 获取元素的类型

                  String elementTypeName =

DataType.getElementTypeName(objTypeName);

                  Class elementCls = ClassReflector.newClass(elementTypeName);

                  int index = 0;

                  // 5.2 解析每个元素对象,放入数组或集合中

                  for (JsonProp p : propList) {

                           // 5.2.1 解析每个元素对象

                           Object elementObj = json2Obj(p.jsonPropValue, elementCls);

                          

                           // 5.2.2 将元素对象放入数组或集合中

                           switch(objType) {

                                     case DataType.DT_Array:

                                              if (obj == null) {

                                                       obj = ClassReflector.newArray(elementCls, propList.size());

                                              }

                                              ClassReflector.setArrayElement(obj, index++, elementObj);

                                              break;

                                     case DataType.DT_List:

                                              ((List)obj).add(elementObj);

                                              break;

                                     case DataType.DT_Map:

                                              ((Map)obj).put(p.propName, elementObj);

                                              break;

                                     case DataType.DT_Set:

                                              ((Set)obj).add(elementObj);

                                              break;

                           }

                  }

                 

                  // 返回转换后的集合对象

                  return (T)obj;

         }

json2Obj 方法实现过程,主要步骤如下:

(1)如果目标Java类是内置类型,则直接进行数据类型转换即可,转换结束;

(2)将JSON串分解为一系列属性结构,每个属性结构用JsonProp 表示;

(3)生成目标Java类的对象实例;

(4)如果目标Java类是自定义对象类型,则对每个JsonProp结构,递归调用json2Obj 方法,将返回的对象设置到目标对象实例相应的属性上,返回目标对象,转换结束;

(5)对数组和集合类型,单独进行处理。这种情况下,需要获取数组或集合内的元素类型,根据元素类型构建相应的元素,然后再放入数组或者集合。

在实现过程,大量使用了递归。

JSON串分解后的每个属性结构,用JsonProp 来表示,定义如下:

package ticd.java.component.json;

public class JsonProp {

         public static final int SIMPLE = 0;

         public static final int ARRAY = 1;

         public static final int OBJECT = 2;

        

         public JsonProp(String propName, int propType, String jsonPropValue) {

                  this.propName = propName;

                  this.propType = propType;

                  this.jsonPropValue = jsonPropValue;

         }

        

         public String propName;

         public int propType;

         public String jsonPropValue;

}

将JSON串分解为一系列JsonProp结构,是由splitProperties() 函数完成的,请读者自行阅读代码。

8.4.2  obj2Json 实现

理解了json2Obj() 方法的实现,再来看obj2Json() 方法,就容易多了。obj2Json() 方法的实现思路,与json2Obj() 方法类似。obj2Json() 方法将Java对象转换为JSON格式的字符串。Java对象可能为如下情况之一:

(1)内置类型:如String, Integer, Date等。

(2)数组:如int[], String[][]等。

(3)集合:如List、Set。

(4)Map。

(5)自定义对象。

(6)以上各种组合:如自定义对象构成的数组。

因此,在实现上,也是递归调用obj2Json方法,直到最基本的类型被转换为Json串。核心代码如下:

         /**

          * 将Java对象转换为JSON字符串

          * @param obj 待转换的Java对象

          * @return 返回转换后的JSON字符串

          */

         public static String obj2Json(Object obj) {

                  int objDataType = DataType.getDataType(obj);

                  if (DataType.isSimpleType(objDataType)) {

                           switch (objDataType) {

                                     case DataType.DT_Character:

                                     case DataType.DT_String:

                                     case DataType.DT_Date:

                                     case DataType.DT_Time:

                                     case DataType.DT_DateTime:

                                              obj = DataType.toType(obj, objDataType, DataType.DT_String);

                                              return "\"" + obj.toString() + "\"";

                                     default:

                                              return obj.toString();

                           }

                  }

                 

                  // 处理复杂类型

                  StringBuilder sb = new StringBuilder();

                  switch (objDataType) {

                  case DataType.DT_Array:

                           sb.append('[');

                           int iLen = Array.getLength(obj);

                           for (int i = 0; i < iLen; i++) {

                                     sb.append(obj2Json(Array.get(obj, i)));

                                     sb.append(", ");

                           }

                           sb.delete(sb.length() - 2, sb.length());

                           sb.append(']');

                           break;

                  case DataType.DT_List:

                           sb.append('[');

                           List list = (List)obj;

                           for (Object o : list) {

                                     sb.append(obj2Json(o));

                                     sb.append(", ");

                           }

                           sb.delete(sb.length() - 2, sb.length());

                            sb.append(']');

                           break;

                  case DataType.DT_Set:

                           sb.append('[');

                           Set set = (Set)obj;

                           Iterator it = set.iterator();

                           while (it.hasNext()) {

                                     sb.append(obj2Json(it.next()));

                                     sb.append(", ");

                           }

                           sb.delete(sb.length() - 2, sb.length());

                           sb.append(']');

                           break;

                  case DataType.DT_Map:

                           sb.append("{");

                           Set entrySet = ((Map)obj).entrySet();

                           Iterator iterator = entrySet.iterator();

                           while (iterator.hasNext()) {

                                     Map.Entry entry = (Map.Entry)iterator.next();

                                     Object key = entry.getKey();

                                     sb.append(key.toString());

                                     sb.append(" : ");

                                    

                                     Object value = entry.getValue();

                                     sb.append(obj2Json(value));

                                     sb.append(", ");

                           }

                           sb.delete(sb.length() - 2, sb.length());

                           sb.append("}");

                           break;

                  case DataType.DT_UserDefine:

                           sb.append("{");

                           ClassReflector reflector = new ClassReflector(obj);

                           int iCount = reflector.getPropertyCount();

                           for (int i = 0; i < iCount; i++) {

                                     String propName = reflector.getPropertyName(i);

                                     sb.append(propName);

                                     sb.append(" : ");

                                    

                                     Object propValue = reflector.getPropertyValue(i);

                                     sb.append(obj2Json(propValue));

                                     sb.append(",\n");

                           }

                           sb.delete(sb.length() - 2, sb.length());

                           sb.append("}");

                           break;

                  default:

                           return obj.toString();

                  }

                 

                  return sb.toString();

         }

代码不是非常复杂,因此请读者自行阅读。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约