标签:
使用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 }
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 }
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 }
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无法反序列化,因为它有一个抽象属性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 }
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 }
1 import java.lang.reflect.InvocationTargetException; 2 import java.lang.reflect.Modifier; 3 4 import net.sf.json.JSONObject; 5 import net.sf.json.JsonConfig; 6 import net.sf.json.util.NewBeanInstanceStrategy; 7 8 public class TestJsonObj { 9 10 private String jsonProp; 11 12 private AbstracObj absProp; 13 14 public String getJsonProp() { 15 return jsonProp; 16 } 17 18 public void setJsonProp(String jsonProp) { 19 this.jsonProp = jsonProp; 20 } 21 22 public AbstracObj getAbsProp() { 23 return absProp; 24 } 25 26 public void setAbsProp(AbstracObj absProp) { 27 this.absProp = absProp; 28 } 29 30 private static JsonConfig unserializableConfig = new JsonConfig(); 31 32 static { 33 // 设置类初始化策略,过滤抽象类 34 unserializableConfig.setNewBeanInstanceStrategy(new NewBeanInstanceStrategy() { 35 36 @Override 37 public Object newInstance(Class c, JSONObject jo) throws InstantiationException, IllegalAccessException, 38 SecurityException, NoSuchMethodException, InvocationTargetException { 39 // 是否为抽象类 40 if (Modifier.isAbstract(c.getModifiers())) { 41 try { 42 // 返回类 43 return Class.forName(jo.getString("clazz")).newInstance(); 44 } 45 catch (Exception e) { 46 e.printStackTrace(); 47 } 48 } 49 return c.newInstance(); 50 } 51 }); 52 } 53 54 /** 55 * 将json字符串反序列化成对象.</p> 56 * 57 * 如果传下来classType的值,则反序列了classType,如果没有传,则json串中必须含有clazz属性,指定json串要反序列化的类型。 58 * 59 * @param json 60 * json字符串 61 * @return 返回对象 62 */ 63 public static Object toObject(String json, Class<?> classType) throws Exception { 64 JSONObject jsonObject = JSONObject.fromObject(json); 65 Class<?> clazz = classType; 66 if (classType != null) { 67 clazz = classType; 68 } 69 else { 70 String clazzName = jsonObject.getString("clazz"); 71 clazz = Class.forName(clazzName); 72 } 73 JsonConfig jsonConfig = unserializableConfig.copy(); 74 jsonConfig.setRootClass(clazz); 75 return JSONObject.toBean(jsonObject, jsonConfig); 76 } 77 78 public static void main(String[] args) { 79 TestJsonObj tb = new TestJsonObj(); 80 tb.setJsonProp("aaaa"); 81 ObjectA oa = new ObjectA(); 82 oa.setPropCommmon("common"); 83 oa.setPropA("propA"); 84 tb.setAbsProp(oa); 85 JSONObject jsonObject = JSONObject.fromObject(tb); 86 System.out.println(jsonObject.toString()); 87 try { 88 System.out.println(toObject(jsonObject.toString(), TestJsonObj.class)); 89 } 90 catch (Exception e) { 91 e.printStackTrace(); 92 } 93 } 94 95 }
ObjectA和ObjectB实现getClazz接口,返回了自己的Class类型。
这时将TestJsonObj序列化后看到absProp增加了clazz属性:
{
"absProp": {
"clazz": "ObjectA",
"propA": "propA",
"propCommmon": "common"
},
"jsonProp": "aaaa"
}
反序列化时实例化clazz类型就可以了,见JsonConfig的配置。
标签:
原文地址:http://www.cnblogs.com/BensonHe/p/4614478.html