由于项目使用的是fastjson,也无法换成其他的序列化框架,所以研究了一下他对泛型序列化和反序列化的支持能力,最终解决了这个问题。

要达成的目标

我的封装方式属于通用封装,我要达到的目标是如下的使用方式:

放入数据:

 Map<String, OffheapDTO> mapxx = new HashMap<>();
mapxx.put("1",new OffheapDTO().create());
mapxx.put("2",new OffheapDTO().create());
mapxx.put("3",new OffheapDTO().create());
mapxx.put("4",new OffheapDTO().create());
mapxx.put("5",new OffheapDTO().create());
offheapCacheWrapper.putMap("maptest", mapxx);

获取数据:

 Map<String, OffheapDTO> resultmap = offheapCacheWrapper.queryMap("cachemap")

OffheapDTO对象的定义方式如下:

class OffheapDTO implements Serializable, Comparable{
private String name;
private String address;
private String mark;
private int order;
//省略getset
}

也就是我可以随意的把任何对象进行序列化操作,然后可以随意的把任何已经序列化的对象,反序列化回来。

第一版代码代码,未中其意

 
putMap方法代码如下:
    public <T> void putMap(String key, T value, long expireSeconds) {
        try {
EntityWrapper<T> entityWrapper = new EntityWrapper<>().create(key, value, expireSeconds);
initMapContainer(OffheapCacheConst.MAP_CONTAINER_FOR_STRING).put(key, JSON.toJSONString(entityWrapper));
} catch (Exception ex) {
logger.error(OffheapCacheConst.PACKAGE_CONTAINER + "putMapSingle with expires exception:", ex);
throw ex;
}
    }

queryMap方法代码如下:

    public <T> T queryMap(String key) {
try {
Object result = initMapContainer(OffheapCacheConst.MAP_CONTAINER_FOR_STRING).get(key);
if(result == null){
return null;
}
//反序列化出entityWrapper
EntityWrapper entityWrapper = JSON.parseObject(result.toString());
return (T)entityWrapper.getEntity();
} catch (Exception ex) {
logger.error(OffheapCacheConst.PACKAGE_CONTAINER + "queryMap exception:", ex);
return null;
}
    }

结果当我反序列化的时候,调用resultmap.get("1")的时候,提示我无法将jsonObject转变成OffheapDTO. 调试进去发现,List对象里面装载的仍然是jsonObject数据。初次尝试失败。

第二版代码,苦尽甘来

之后翻看了百度,查阅了大量资料,然后看到了关于TypeReference的代码,之后将queryMap方法修改如下:

    public <T> T queryMap(String key) {
try {
Object result = initMapContainer(OffheapCacheConst.MAP_CONTAINER_FOR_STRING).get(key);
if(result == null){
return null;
}
//反序列化出entityWrapper
EntityWrapper entityWrapper = JSON.parseObject(result.toString(),new TypeReference<EntityWrapper<T>>() {});
            return (T)entityWrapper.getEntity();
} catch (Exception ex) {
logger.error(OffheapCacheConst.PACKAGE_CONTAINER + "queryMap exception:", ex);
return null;
}
}

注意代码中黄色部分。

然后当我再次进行反序列化的时候,我发现resultMap.get(“1”)已经可以拿到正常的OffheapDTO对象了。心中一喜,然后运行resultMap.get(“1”).getName(), 居然又报错,提示无法将jsonObject转变成OffheapDTO对象,发现原来存储的字段,居然都是jsonObject类型。这次就有点慌了。

第三版代码,蓦然回首

不过想想fastjson这么成熟,定然有前人的轮子,所以就继续查阅资料,终于查到了setAutoTypeSupport这个属性,没想到一试,居然解决了问题。

首先,程序启动的时候,需要开启这个属性,至于这个属性真正的意义,去翻阅fastjson文档,我这里就不赘述了:

      //开启fastjson autotype功能(不开启,造成EntityWrapper<T>中的T无法正常解析)
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);

然后,在序列化的时候,需要附带上序列化的class名称(黄色标记部分):

    public <T> void putMap(String key, T value, long expireSeconds) {
try {
EntityWrapper<T> entityWrapper = new EntityWrapper<>().create(key, value, expireSeconds);
initMapContainer(OffheapCacheConst.MAP_CONTAINER_FOR_STRING).put(key, JSON.toJSONString(entityWrapper, SerializerFeature.WriteClassName));
        } catch (Exception ex) {
logger.error(OffheapCacheConst.PACKAGE_CONTAINER + "putMapSingle with expires exception:", ex);
throw ex;
}
}

最后,在反序列化的时候,利用TypeReference进行类型指定即可:

    public <T> T queryMap(String key) {
try {
Object result = initMapContainer(OffheapCacheConst.MAP_CONTAINER_FOR_STRING).get(key);
if(result == null){
return null;
}
//反序列化出entityWrapper
EntityWrapper entityWrapper = JSON.parseObject(result.toString(),new TypeReference<EntityWrapper<T>>() {});
            return (T)entityWrapper.getEntity();
} catch (Exception ex) {
logger.error(OffheapCacheConst.PACKAGE_CONTAINER + "queryMap exception:", ex);
return null;
}
}

这样,无论你的类有多复杂,都可以搞定,比如像下面这样的:

Map<String,List< OffheapDTO>> resultmap = offheapCacheWrapper.queryMap("maptest");

甚至这样的:

List<Map<String,List<Set<OffheapDTO>>>> resultmap = offheapCacheWrapper.queryMap("maptest");

Enjoy!!

基于FastJson的通用泛型解决方案的更多相关文章

  1. 基于dapper的通用泛型分页

    1.定义一个用来装载适合所有类的分页结果类 public class PageDataView<T> { private int _TotalNum; public PageDataVie ...

  2. Fastjson解析多级泛型的几种方式—使用class文件来解析多级泛型

    Fastjson解析多级泛型 前言 现在网上大多数是使用TypeReference 方式来解析JSON数据,这里我提供另外一种方式来解析,使用类文件进行解析,两种方式我都会给出实际代码 实例 Type ...

  3. 基于.net的分布式系统限流组件 C# DataGridView绑定List对象时,利用BindingList来实现增删查改 .net中ThreadPool与Task的认识总结 C# 排序技术研究与对比 基于.net的通用内存缓存模型组件 Scala学习笔记:重要语法特性

    基于.net的分布式系统限流组件   在互联网应用中,流量洪峰是常有的事情.在应对流量洪峰时,通用的处理模式一般有排队.限流,这样可以非常直接有效的保护系统,防止系统被打爆.另外,通过限流技术手段,可 ...

  4. #研发解决方案介绍#基于StatsD+Graphite的智能监控解决方案

    郑昀 基于李丹和刘奎的文档 创建于2014/12/5 关键词:监控.dashboard.PHP.graphite.statsd.whisper.carbon.grafana.influxdb.Pyth ...

  5. 构建一个基本的前端自动化开发环境 —— 基于 Gulp 的前端集成解决方案(四)

    通过前面几节的准备工作,对于 npm / node / gulp 应该已经有了基本的认识,本节主要介绍如何构建一个基本的前端自动化开发环境. 下面将逐步构建一个可以自动编译 sass 文件.压缩 ja ...

  6. 常用 Gulp 插件汇总 —— 基于 Gulp 的前端集成解决方案(三)

    前两篇文章讨论了 Gulp 的安装部署及基本概念,借助于 Gulp 强大的 插件生态 可以完成很多常见的和不常见的任务.本文主要汇总常用的 Gulp 插件及其基本使用,需要读者对 Gulp 有一个基本 ...

  7. 在windows下安装gulp —— 基于 Gulp 的前端集成解决方案(一)

    相关连接导航 在windows下安装gulp —— 基于 Gulp 的前端集成解决方案(一) 执行 $Gulp 时发生了什么 —— 基于 Gulp 的前端集成解决方案(二) 常用 Gulp 插件汇总 ...

  8. 执行 $Gulp 时发生了什么 —— 基于 Gulp 的前端集成解决方案(二)

    前言 文章 在windows下安装gulp —— 基于 Gulp 的前端集成解决方案(一) 中,已经完成对 gulp 的安装,由于是window环境,文中特意提到了可以通过安装 gitbash 来代替 ...

  9. Java魔法堂:解读基于Type Erasure的泛型

    一.前言 还记得JDK1.4时遍历列表的辛酸吗?我可是记忆犹新啊,那时因项目需求我从C#转身到Java的怀抱,然后因JDK1.4少了泛型这样语法糖(还有自动装箱.拆箱),让我受尽苦头啊,不过也反映自己 ...

随机推荐

  1. 【LeetCode每天一题】Jump Game II(跳跃游戏II)

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...

  2. Python:遍历一个目录下所有的文件及文件夹,然后计算每个文件的字符和line的小程序

    编写了一个遍历一个目录下所有的文件及文件夹,然后计算每个文件的字符和line的小程序,先把程序贴出来. #coding=utf-8 ''' Created on 2014年7月14日 @author: ...

  3. Ajax 监听

    $.ajaxSetup({ beforeSend: function (XMLHttpRequest) { alert("ajax请求之前"); } });

  4. 与数论的厮守02:整数的因子分解—Pollard_Rho

    学Pollard_Rho之前,你需要学会:Miller Rabin. 这是一个很高效的玄学算法,用来对大整数进行因数分解. 我们来分解n.若n是一个素数,那么就不需要分解了.所以我们还得能够判断一个数 ...

  5. 检查文件是否被修改或者被破坏工具 md5

    检查文件和对应的md5值是否一致.

  6. windows程序设计 vs2012 新建win32项目

    1.文件->新建->项目 2.选择win32项目,确定 3.下一步 4.选择windows应用程序,选中空项目,安全开发生命周期不选.点击完成. 5.空项目建好了.

  7. .NET 4.5 中新提供的压缩类(转载)

    Windows8 的开发已经如火如荼开始了,在 Windows8 中提供的 .NET Framework 已经更新到了 4.5 版,其中又增加了一些新的特性,对压缩文件的支持就是其中之一. 在 4.5 ...

  8. Hbase伪分布式安装

    前面的文章已经讲过hadoop伪分布式安装,这里直接介绍hbase伪分布式安装. 1. 下载hbase 版本hbase 1.2.6 2. 解压hbase 3. 修改hbase-env.sh 新增如下内 ...

  9. dva构建react项目

    第一步:安装 dva-cli 1 cnpm install dva-cli -g 第二步:采用dva来创建项目: 1 dva new react_two 2 cd react_two 用webstor ...

  10. Redis学习-hash数据类型

    hash 类型是string类型的field和value的映射表,或者说是一个string集合,适合存储对象,相比较而言,将一个对象类型存储在hash类型里要比存储在string类型里占用更少的内存空 ...