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的配置。

 

你可能感兴趣的:(json-lib)