json-lib反序列化抽象属性及对象

使用json默认反序列化接口反序列化对象时,对象的类型必须的确定的,比如不能是抽象类型,否则会报无法实例化对象的异常

如有下列类定义:

 1 public abstract class AbstracObj {
 2 
 3     private String propCommmon;
 4 
 5     public String getPropCommmon() {
 6         return propCommmon;
 7     }
 8 
 9     public void setPropCommmon(String propCommmon) {
10         this.propCommmon = propCommmon;
11     }
12 
13 }
AbstracObj
 1 public class ObjectA extends AbstracObj{
 2 
 3     private String propA;
 4 
 5     public String getPropA() {
 6         return propA;
 7     }
 8 
 9     public void setPropA(String propA) {
10         this.propA = propA;
11     }
12 
13 }
ObjectA
 1 public class ObjectB extends AbstracObj{
 2 
 3     private String propB;
 4 
 5     public String getPropB() {
 6         return propB;
 7     }
 8 
 9     public void setPropB(String propB) {
10         this.propB = propB;
11     }
12 
13 }
ObjectB
 1 import net.sf.json.JSONObject;
 2 
 3 public class TestJsonObj {
 4 
 5     private String jsonProp;
 6 
 7     private AbstracObj absProp;
 8 
 9     public String getJsonProp() {
10         return jsonProp;
11     }
12 
13     public void setJsonProp(String jsonProp) {
14         this.jsonProp = jsonProp;
15     }
16 
17     public AbstracObj getAbsProp() {
18         return absProp;
19     }
20 
21     public void setAbsProp(AbstracObj absProp) {
22         this.absProp = absProp;
23     }
24 
25     public static void main(String[] args) {
26         TestJsonObj tb = new TestJsonObj();
27         tb.setJsonProp("aaaa");
28         ObjectA oa = new ObjectA();
29         oa.setPropCommmon("common");
30         oa.setPropA("propA");
31         tb.setAbsProp(oa);
32         JSONObject jsonObject = JSONObject.fromObject(tb);
33         jsonObject.toBean(jsonObject, TestJsonObj.class);
34     }
35 }
TestJsonObj

TestJsonObj无法反序列化,因为它有一个抽象属性absProp。

可以通过增加标志抽象对象的类型属性及重载json-lib反序列化的接口实现。

定义接口Jsonable,让对象实现这个接口:

 1 public class ObjectA extends AbstracObj implements Jsonable {
 2 
 3     private String propA;
 4 
 5     public String getPropA() {
 6         return propA;
 7     }
 8 
 9     public void setPropA(String propA) {
10         this.propA = propA;
11     }
12 
13     @Override
14     public Class<?> getClazz() {
15         return ObjectA.class;
16     }
17 
18 }
ObjectA
 1 public class ObjectB extends AbstracObj implements Jsonable {
 2 
 3     private String propB;
 4 
 5     public String getPropB() {
 6         return propB;
 7     }
 8 
 9     public void setPropB(String propB) {
10         this.propB = propB;
11     }
12 
13     @Override
14     public Class<?> getClazz() {
15         return ObjectB.class;
16     }
17 
18 }
ObjectB
  1 package com.mucfc.mpf.utils;
  2 
  3 import java.lang.reflect.Array;
  4 import java.lang.reflect.InvocationTargetException;
  5 import java.lang.reflect.Modifier;
  6 import java.util.List;
  7 
  8 import net.sf.json.JSONArray;
  9 import net.sf.json.JSONObject;
 10 import net.sf.json.JsonConfig;
 11 import net.sf.json.util.JSONTokener;
 12 import net.sf.json.util.NewBeanInstanceStrategy;
 13 
 14 import com.lz.lsf.exception.ServiceException;
 15 import com.lz.lsf.exception.SystemException;
 16 import com.mucfc.mpf.common.exception.MpfErrorCode;
 17 
 18 /**
 19  * json序列化反序列化帮助类
 20  * 
 21  * @author hebeisheng
 22  * @Since 2015/7/1
 23  *
 24  */
 25 public class JsonUtil {
 26 
 27     private static JsonConfig unserializableConfig = new JsonConfig();
 28 
 29     static {
 30         // 设置类初始化策略,过滤抽象类
 31         unserializableConfig.setNewBeanInstanceStrategy(new NewBeanInstanceStrategy() {
 32 
 33             @Override
 34             public Object newInstance(Class c, JSONObject jo) throws InstantiationException, IllegalAccessException,
 35                     SecurityException, NoSuchMethodException, InvocationTargetException {
 36                 // 是否为抽象类
 37                 if (Modifier.isAbstract(c.getModifiers())) {
 38                     try {
 39                         // 返回类
 40                         return Class.forName(jo.getString("clazz")).newInstance();
 41                     }
 42                     catch (Exception e) {
 43                         e.printStackTrace();
 44                     }
 45                 }
 46                 return c.newInstance();
 47             }
 48         });
 49     }
 50 
 51     /**
 52      * 将对象转成Json字符串
 53      * 
 54      * @param object
 55      *            对象
 56      * @return 返回 Json字符串
 57      */
 58     public static String toJson(Object object) {
 59         if (List.class.isAssignableFrom(object.getClass())) {
 60             JSONArray array = JSONArray.fromObject(object);
 61             return array.toString();
 62         }
 63         JSONObject jsonObject = JSONObject.fromObject(object);
 64         return jsonObject.toString();
 65     }
 66 
 67     /**
 68      * 将json字符串反序列化成对象.</p>
 69      * 
 70      * 如果传下来classType的值,则反序列了classType,如果没有传,则json串中必须含有clazz属性,指定json串要反序列化的类型。
 71      * 
 72      * @param json
 73      *            json字符串
 74      * @return 返回对象
 75      */
 76     public static Object toObject(String json, Class<?> classType) throws ServiceException {
 77         Object jsonObj = new JSONTokener(json).nextValue();
 78         JsonConfig jsonConfig = unserializableConfig.copy();
 79         
 80         //JSONArray和JSONObject不兼容,所以要先判断类型
 81         if (jsonObj instanceof JSONArray) {
 82             ArgumentChecker.notNull("classType", classType);
 83             jsonConfig.setRootClass(classType);
 84             JSONArray jsonArray = (JSONArray) jsonObj;
 85             if (Array.class.isAssignableFrom(classType)) {
 86                 return JSONArray.toArray(jsonArray, jsonConfig);
 87             }
 88             return JSONArray.toCollection(jsonArray, jsonConfig);
 89         }
 90 
 91         JSONObject jsonObject = (JSONObject) jsonObj;
 92         Class<?> clazz = classType;
 93         if (classType != null) {
 94             clazz = classType;
 95         }
 96         else {
 97             String clazzName = jsonObject.getString("clazz");
 98             try {
 99                 clazz = Class.forName(clazzName);
100             }
101             catch (ClassNotFoundException e) {
102                 throw new SystemException(MpfErrorCode.SYSTEM_ERROR, "实例化" + clazzName + "失败");
103             }
104         }
105         jsonConfig.setRootClass(clazz);
106         return JSONObject.toBean(jsonObject, jsonConfig);
107     }
108 }
TestJsonObj

ObjectA和ObjectB实现getClazz接口,返回了自己的Class类型。

这时将TestJsonObj序列化后看到absProp增加了clazz属性:

{
    "absProp": {
        "clazz": "ObjectA",
        "propA": "propA",
        "propCommmon": "common"
    },
    "jsonProp": "aaaa"
}
Json串

反序列化时实例化clazz类型就可以了,见JsonConfig的配置。

 

posted @ 2015-07-01 20:31  涂墨留香  阅读(1211)  评论(0编辑  收藏  举报