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}; ...
随机推荐
- [UVa OJ] Longest Common Subsequence
This is the classic LCS problem. Since it only requires you to print the maximum length, the code ca ...
- delphi xe---intraweb基本介绍
版本10 seattle 新建intraWeb new->other->Delphi Projecs->IntraWeb->IntraWeb Application wizar ...
- 超哥带你学网络编程部分blog
https://www.cnblogs.com/clschao/articles/9593164.html 网络编程 https://www.cnblogs.com/clschao/articles ...
- [刷题]ACM ICPC 2016北京赛站网络赛 D - Pick Your Players
Description You are the manager of a small soccer team. After seeing the shameless behavior of your ...
- Unix file types
w https://en.wikipedia.org/wiki/Unix_file_types A socket is a special file used for inter-process co ...
- php自定义函数: 下载本地服务器的大文件
// 使用方法 $file_path = './a.zip'; // 只能是本地服务器文件, 多大的文件都支持!! down_file($file_path); // 函数参数: 服务器文件路径,下载 ...
- Tornado实战
抽屉之Tornado实战(1)--分析与架构 抽屉之Tornado实战(2)--数据库表设计 抽屉之Tornado实战(3)--注册 抽屉之Tornado实战(4)--发帖及上传图片 抽屉之Torna ...
- 利用kubeadm部署kubernetes 1.7 with flannel
一.Installation 1.安装环境为CentOS 7 2.安装Docker yum install -y docker systemctl enable docker systemctl st ...
- 我的Android进阶之旅------>解决Error: specified for property 'mergedManifest' does not exist.
错误描述 刚运行从Github上面下载而来的代码时,爆了如下所示的bug,错误描述如下所示: Error:A problem was found with the configuration of t ...
- 谷歌公布全新设计语言:跟苹果Swift天差地别
今日凌晨.谷歌(微博)在I/O大会上公布了全新设计语言Material Design.在20多天前的WWDC上.苹果也公布了全新编程语言Swift.两家科技巨头公司,在一年一度的开发人员大会上,都公布 ...