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}; ...
随机推荐
- 【转】Spring MVC 3.x 基本配置
WEB-INF/web.xml 例1 <?xml version="1.0" encoding="UTF-8"?> <web-app xmln ...
- Storm 架构图
画的丑,勉强看看吧 Nimbus我感觉他就像人的大脑一样! 当客户端给这个人发送了段信息 ,这个人的大脑就接收到这段信息,这个人不简单,是幕后大佬,一般不自己去干活,都是交给下面二当家去执行,当时这个 ...
- IE11上登陆oracle OEM时报:“证书错误,导航已阻止”且无继续浏览此网站(不推荐)的错误
问题原因:oracle oem证书的密钥小于1024 解决方案:在cmd中执行命令:certutil -setreg chain\EnableWeakSignatureFlags 8 出现以下提示: ...
- php 问题及原因总结
1.php 加水印时出现问题的原因 :或许某个参数输入错误,导致页面一点反应都没有.
- python2 一些错误处理
python2各种问题 pip安装django出错:python2 -m pip install django 编码问题:Unicode Decode Error ascii codec can't ...
- selenium入门基础知识
内容转载自:http://blog.csdn.net/huangbowen521/article/details/7816538 1.selenium介绍: Selenium是一个浏览器自动化操作框架 ...
- Canvas的save和restore
在onDraw方法里,我们经常会看到调用save和restore方法,它们到底是干什么用的呢? int px = getMeasuredWidth(); int py = getMeasuredWid ...
- New Moto X 2014 全版本官方解锁Bootloader图文教程
]秒后松开,手机就会进入fastboot模式. 如下图: <ignore_js_op> 接下来,手机连接电脑,打开刚刚的fastboot工具里面的命令提示符: <ignore_js_ ...
- python全栈开发从入门到放弃之字符编码
一 了解字符编码的知识储备 1. 计算机基础知识(三幅图) 2. 文本编辑器存取文件的原理(nodepad++,pycharm,word) 打开编辑器就打开了启动了一个进程,是在内存中 ...
- django-ORM复习补充
建表 class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() # ...