使用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. https://www.cnblogs.com/yuanchenqi/articles/6755717.html

    知识预览 一 进程与线程的概念 二 threading模块 三 multiprocessing模块 四 协程 五 IO模型 回到顶部 一 进程与线程的概念 1.1 进程 考虑一个场景:浏览器,网易云音 ...

  2. ArcGIS Silverlight 设置token

    背景 arcgis for server采用多种安全认证方式.常用的就是就是采用token机制.所以对服务设置了安全,则前端需要提供相对应的token凭证.通常来说设置token有以下两种情形: 一是 ...

  3. flask大全

    django:重武器,内部包含了非常多组件:ORM.Form.ModelForm.缓存.Session,中间件,信号等... flask:短小精悍.内部没有太多组件,第三方组件非常丰富 1.初识fla ...

  4. 在MyEclipse中改了项目名称,到tomcat的webroot下发现,部署的名称还是原来的。

    在MyEclipse中改了项目名称,到tomcat的webroot下发现,部署的名称还是原来的. 解决方法:选中项目名称右键properties,展开Myeclipse,选择web,web Conte ...

  5. Python3+Selenium3自动化测试-(五)

    这里来说一说selenium中的等待方式,其实在webdriver只有两种类型等待方式,显式等待和隐式等待,之前是在程序运行过程中使用time模块中的sleep进行代码的休眠进行强制等待,是显式等待中 ...

  6. sql server安装教程(2008 R2,图形界面安装/命令提示符安装即静默安装)

    转自:http://blog.51cto.com/jimshu/585023 SQL Server 2008(32/64位)下载地址: 链接:https://pan.baidu.com/s/1eR5b ...

  7. use html5 video tag with MSE for h264 live streaming

    本编博客记录桌面虚拟化移动端预研. 完整demo: https://github.com/MarkRepo/wfs.js 常见的直播方案有RTMP RTSP HLS 等等, 由于这些流都需要先传输到服 ...

  8. Django web 框架

    目录 与Django的第一次见面 安装.文件解释与基本命令 Settings Models Views 路由系统 模板 Form表单 Cookie与Session CSRF防护

  9. SignalTap II进阶学习

    1. 多级触发 有时候我们可能需要利用多个信号(最多10个)依次触发后,观察特定的值.这这时候我们可以增加触发条件来满足我们的需求. 多个触发信号如上图所示,只有依次发生SW[0]上升沿. SW[1] ...

  10. Web框架(Day64)

    阅读目录 http协议 web应用与web框架 一.http协议 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World W ...