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

如有下列类定义:

 public abstract class AbstracObj {

     private String propCommmon;

     public String getPropCommmon() {
return propCommmon;
} public void setPropCommmon(String propCommmon) {
this.propCommmon = propCommmon;
} }

AbstracObj

 public class ObjectA extends AbstracObj{

     private String propA;

     public String getPropA() {
return propA;
} public void setPropA(String propA) {
this.propA = propA;
} }

ObjectA

 public class ObjectB extends AbstracObj{

     private String propB;

     public String getPropB() {
return propB;
} public void setPropB(String propB) {
this.propB = propB;
} }

ObjectB

 import net.sf.json.JSONObject;

 public class TestJsonObj {

     private String jsonProp;

     private AbstracObj absProp;

     public String getJsonProp() {
return jsonProp;
} public void setJsonProp(String jsonProp) {
this.jsonProp = jsonProp;
} public AbstracObj getAbsProp() {
return absProp;
} public void setAbsProp(AbstracObj absProp) {
this.absProp = absProp;
} public static void main(String[] args) {
TestJsonObj tb = new TestJsonObj();
tb.setJsonProp("aaaa");
ObjectA oa = new ObjectA();
oa.setPropCommmon("common");
oa.setPropA("propA");
tb.setAbsProp(oa);
JSONObject jsonObject = JSONObject.fromObject(tb);
jsonObject.toBean(jsonObject, TestJsonObj.class);
}
}

TestJsonObj

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

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

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

 public class ObjectA extends AbstracObj implements Jsonable {

     private String propA;

     public String getPropA() {
return propA;
} public void setPropA(String propA) {
this.propA = propA;
} @Override
public Class<?> getClazz() {
return ObjectA.class;
} }

ObjectA

 public class ObjectB extends AbstracObj implements Jsonable {

     private String propB;

     public String getPropB() {
return propB;
} public void setPropB(String propB) {
this.propB = propB;
} @Override
public Class<?> getClazz() {
return ObjectB.class;
} }

ObjectB

 package com.mucfc.mpf.utils;

 import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.List; import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.JSONTokener;
import net.sf.json.util.NewBeanInstanceStrategy; import com.lz.lsf.exception.ServiceException;
import com.lz.lsf.exception.SystemException;
import com.mucfc.mpf.common.exception.MpfErrorCode; /**
* json序列化反序列化帮助类
*
* @author hebeisheng
* @Since 2015/7/1
*
*/
public class JsonUtil { private static JsonConfig unserializableConfig = new JsonConfig(); static {
// 设置类初始化策略,过滤抽象类
unserializableConfig.setNewBeanInstanceStrategy(new NewBeanInstanceStrategy() { @Override
public Object newInstance(Class c, JSONObject jo) throws InstantiationException, IllegalAccessException,
SecurityException, NoSuchMethodException, InvocationTargetException {
// 是否为抽象类
if (Modifier.isAbstract(c.getModifiers())) {
try {
// 返回类
return Class.forName(jo.getString("clazz")).newInstance();
}
catch (Exception e) {
e.printStackTrace();
}
}
return c.newInstance();
}
});
} /**
* 将对象转成Json字符串
*
* @param object
* 对象
* @return 返回 Json字符串
*/
public static String toJson(Object object) {
if (List.class.isAssignableFrom(object.getClass())) {
JSONArray array = JSONArray.fromObject(object);
return array.toString();
}
JSONObject jsonObject = JSONObject.fromObject(object);
return jsonObject.toString();
} /**
* 将json字符串反序列化成对象.</p>
*
* 如果传下来classType的值,则反序列了classType,如果没有传,则json串中必须含有clazz属性,指定json串要反序列化的类型。
*
* @param json
* json字符串
* @return 返回对象
*/
public static Object toObject(String json, Class<?> classType) throws ServiceException {
Object jsonObj = new JSONTokener(json).nextValue();
JsonConfig jsonConfig = unserializableConfig.copy(); //JSONArray和JSONObject不兼容,所以要先判断类型
if (jsonObj instanceof JSONArray) {
ArgumentChecker.notNull("classType", classType);
jsonConfig.setRootClass(classType);
JSONArray jsonArray = (JSONArray) jsonObj;
if (Array.class.isAssignableFrom(classType)) {
return JSONArray.toArray(jsonArray, jsonConfig);
}
return JSONArray.toCollection(jsonArray, jsonConfig);
} JSONObject jsonObject = (JSONObject) jsonObj;
Class<?> clazz = classType;
if (classType != null) {
clazz = classType;
}
else {
String clazzName = jsonObject.getString("clazz");
try {
clazz = Class.forName(clazzName);
}
catch (ClassNotFoundException e) {
throw new SystemException(MpfErrorCode.SYSTEM_ERROR, "实例化" + clazzName + "失败");
}
}
jsonConfig.setRootClass(clazz);
return JSONObject.toBean(jsonObject, jsonConfig);
}
}

TestJsonObj

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

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

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

Json串

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

json-lib反序列化抽象属性及对象的更多相关文章

  1. JSON 转含有泛型属性的对象

    在将 json 字符串转为对象时,如果对象含有泛型,在进行转换时需要指明泛型类型. 1. 对象只含有一个泛型属性时 1.1  代码 /** * @Describe: * @Author: chenfa ...

  2. JSON实现序列化dump和dumps方法,JSON实现反序列化loads和load方法

    通过文件操作,我们可以将字符串写入到一个本地文件.但是,如果是一个对象(例如列表.字典.元组等),就无 法直接写入到一个文件里,需要对这个对象进行序列化,然后才能写入到文件里. 设计一套协议,按照某种 ...

  3. .Net使用Newtonsoft.Json.dll(JSON.NET)对象序列化成json、反序列化json示例教程

    JSON作为一种轻量级的数据交换格式,简单灵活,被很多系统用来数据交互,作为一名.NET开发人员,JSON.NET无疑是最好的序列化框架,支持XML和JSON序列化,高性能,免费开源,支持LINQ查询 ...

  4. Json.net对于导航属性的处理(解决对象循环引用)

    对于两张表A.B多对多的关系中,A的导航属性中有B,B的导航属性中有A,这样Json.net对A或者B对象序列化时会形成死循环 所以对于导航属性要加标签 首先在A.B实体类工程(Model)中引用Js ...

  5. 使用 JSON.parse 反序列化 ISO 格式的日期字符串, 将返回Date格式对象

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. 含有Date属性的对象转化为Json

    含有Date类型属性的对象,转化为Json,Date属性并不是时间戳格式. 解决方法: 使用Jackson的注解@JsonFormat,添加到对象属性上方即可. 我们的北京时间会相差8个小时,因为我们 ...

  7. 类属性与对象实现,init方法的作用,绑定方法,绑定方法与普通函数的区别,继承,抽象与继承,派生与覆盖

    今日内容: 1.类属性与对象属性 2.init方法的作用 3.绑定方法 4.绑定方法与普通函数的区别(非绑定方法) 5.继承 6.抽象与继承 7.派生与覆盖 1.类属性与对象属性 类中应该进存储所有对 ...

  8. 使用JsonConfig控制JSON lib序列化

    将对象转换成字符串,是非常常用的功能,尤其在WEB应用中,使用 JSON lib 能够便捷地完成这项工作.JSON lib能够将Java对象转成json格式的字符串,也可以将Java对象转换成xml格 ...

  9. spring mvc接收ajax提交的JSON数据,并反序列化为对象

    需求:spring mvc接收ajax提交的JSON数据,并反序列化为对象,代码如下: 前台JS代码: //属性要与带转化的对象属性对应 var param={name:'语文',price:16}; ...

随机推荐

  1. Vue.js_数据绑定

    一.文本 data {{data}} <div id="div1">{{message}}</div> <script> var div1 = ...

  2. 常用的mysql语句

    为了方便学习mysql,把接触到的sql收集一下,忘记的时候可以查询一下. 连接mysql数据库: mysql -u 用户名 -p 输入密码. 创建数据库: create database 数据库名; ...

  3. 使用Dell R710 IDRAC挂载虚拟介质

    Dell DRAC,虚拟介质分离或所选虚拟磁盘驱动器的虚拟介质重定向已由另一用户使用 DELL Idrac 一台Dell的R710服务器,远程管理器后发现虚拟介质无法映射,一直提示“虚拟介质分离或所选 ...

  4. Let's encrypt申请泛域名证书以及报错处理

    申请泛域名证书的步骤请参考该链接地址: https://www.jianshu.com/p/df6d13187578 报错信息: No matching distribution found for ...

  5. IOS And WCF 上传文件

    IOS And WCF Story 研究IOS上传到WCF图片的小功能,WCF实现服务端的文件上传的例子很多,单独实现IOS发送图片的例子也很多,但是两个结合起来的就很少了. 可以通过base64来上 ...

  6. xshell 没有反应---Xshell按ctrl+s界面无反应的解决办法

    在用Xshell管理远程服务器,特别是在用vi编辑配置文件时,总是习惯的用ctrl+s想要保存文件,然后就悲剧了.xsell就再也没有返应只能关了重新打开.但原来修改的文件算是报废了. 在网上搜索了一 ...

  7. 剑指Offer——斐波那契数列

    题目描述: 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项.n<=39 分析: 递归解法肯定相当耗时. 因为当n=4时,程序是这样子递归运算的:Fibonacci( ...

  8. Python位运算符

    按位运算符是把数字看作二进制来进行计算的.Python中的按位运算法则如下: 下表中变量 a 为 60,b 为 13,二进制格式如下: a = 0011 1100 b = 0000 1101 ---- ...

  9. Yii2.0的乐观锁与悲观锁(转)

    原文:Yii2.0的乐观锁与悲观锁 Web应用往往面临多用户环境,这种情况下的并发写入控制, 几乎成为每个开发人员都必须掌握的一项技能. 在并发环境下,有可能会出现脏读(Dirty Read).不可重 ...

  10. 001-ant design pro安装、目录结构、项目加载启动【原始、以及idea开发】

    一.概述 1.1.脚手架概念 编程领域中的“脚手架(Scaffolding)”指的是能够快速搭建项目“骨架”的一类工具.例如大多数的React项目都有src,public,webpack配置文件等等, ...