json-lib反序列化抽象属性及对象
使用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反序列化抽象属性及对象的更多相关文章
- JSON 转含有泛型属性的对象
在将 json 字符串转为对象时,如果对象含有泛型,在进行转换时需要指明泛型类型. 1. 对象只含有一个泛型属性时 1.1 代码 /** * @Describe: * @Author: chenfa ...
- JSON实现序列化dump和dumps方法,JSON实现反序列化loads和load方法
通过文件操作,我们可以将字符串写入到一个本地文件.但是,如果是一个对象(例如列表.字典.元组等),就无 法直接写入到一个文件里,需要对这个对象进行序列化,然后才能写入到文件里. 设计一套协议,按照某种 ...
- .Net使用Newtonsoft.Json.dll(JSON.NET)对象序列化成json、反序列化json示例教程
JSON作为一种轻量级的数据交换格式,简单灵活,被很多系统用来数据交互,作为一名.NET开发人员,JSON.NET无疑是最好的序列化框架,支持XML和JSON序列化,高性能,免费开源,支持LINQ查询 ...
- Json.net对于导航属性的处理(解决对象循环引用)
对于两张表A.B多对多的关系中,A的导航属性中有B,B的导航属性中有A,这样Json.net对A或者B对象序列化时会形成死循环 所以对于导航属性要加标签 首先在A.B实体类工程(Model)中引用Js ...
- 使用 JSON.parse 反序列化 ISO 格式的日期字符串, 将返回Date格式对象
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 含有Date属性的对象转化为Json
含有Date类型属性的对象,转化为Json,Date属性并不是时间戳格式. 解决方法: 使用Jackson的注解@JsonFormat,添加到对象属性上方即可. 我们的北京时间会相差8个小时,因为我们 ...
- 类属性与对象实现,init方法的作用,绑定方法,绑定方法与普通函数的区别,继承,抽象与继承,派生与覆盖
今日内容: 1.类属性与对象属性 2.init方法的作用 3.绑定方法 4.绑定方法与普通函数的区别(非绑定方法) 5.继承 6.抽象与继承 7.派生与覆盖 1.类属性与对象属性 类中应该进存储所有对 ...
- 使用JsonConfig控制JSON lib序列化
将对象转换成字符串,是非常常用的功能,尤其在WEB应用中,使用 JSON lib 能够便捷地完成这项工作.JSON lib能够将Java对象转成json格式的字符串,也可以将Java对象转换成xml格 ...
- spring mvc接收ajax提交的JSON数据,并反序列化为对象
需求:spring mvc接收ajax提交的JSON数据,并反序列化为对象,代码如下: 前台JS代码: //属性要与带转化的对象属性对应 var param={name:'语文',price:16}; ...
随机推荐
- cdr X6 64位32位缩略图补丁包
cdr X6 64位32位缩略图补丁包下载 安装了X6没有缩略图的话,点击下面链接下载安装插件即可 点击下载
- 三种系统监控工具对比:top vs Htop vs Glances
首先启用 EPEL Repository: yum -y install epel-release 启用 EPEL Repository 後, 可以用 yum 直接安裝 Htop: yum -y in ...
- 2015-03-10——简析javascript对象
对于构造函数,它是Function对象的一个实例,可以定义自己的静态成员先实例化出对象,后执行function中内部代码 静态成员: var abc = function () {}; //既是一 ...
- Redis与Memcached的比较(转)
原文:http://blog.nosqlfan.com/html/3729.html 这两年Redis火得可以,Redis也常常被当作Memcached的挑战者被提到桌面上来.关于Redis与Memc ...
- 我的Android进阶之旅------>RxJava学习资料汇总
在响应式编程中,应该牢记以下两点: everything is a stream(一切皆流) don't break the chain(不要打断链式结构) 记住,可观测序列就像一条河,它们是流动的. ...
- tomcat 是如何处理jsp和servlet请求
我们以一个具体的例子,来跟踪TOMCAT, 看看它是如何把Request一层一层地递交给下一个容器, 并最后交给Wrapper来处理的. 以http://localhost:8080/web/logi ...
- Java并发—java.util.concurrent.locks包
一.synchronized的缺陷 synchronized是java中的一个关键字,也就是说是Java语言内置的特性.那么为什么会出现Lock呢? 如果一个代码块被synchronized修饰了,当 ...
- redmine集成git
步骤: redmine服务器 1. 在下载安装GIT客户端 下载地址: https://git-scm.com/ 2. 在redmine服务器上将对应项目的git镜像到本地(不是源码下载到本地 ...
- Python面试题之Python对象反射、类反射、模块反射
python面向对象中的反射:通过字符串的形式操作对象相关的属性.python中的一切事物都是对象(都可以使用反射) 一.getattr 对象获取 class Manager: role = &quo ...
- Linux系统crontab定时调度Python脚本
Linux系统crontab定时调度Python脚本 一.Python脚本随Linux开机自动运行 #Python脚本:/home/edgar/auto.py #用root权限编辑以下文件:/etc/ ...