https://github.com/inshua/d2js/blob/master/WebContent/guide/memcached-session.md

基于 https://github.com/magro/memcached-session-manager 实现了一个转换器: org.siphon.javakaffee.msm.NashornTranscoderFactory,利用这个转换器可以将 session 中的 java 及 nashorn js 对象转为 json 后存入 memcached(memcached-session-manager 也支持存入 redis 等,详见其文档)。

思路:

序列化:构造一个待转换的混杂 java 和 nashorn js 的对象:

		ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
JsEngineUtil.initEngine(engine, new Object[] {});
final JSON nashornJson = new JSON(engine);
engine.eval("user = {name:'tom', gender:'m'}");
Object user = engine.get("user"); HashMap<String, Object> map = new HashMap<>();
map.put("jsUser", user);  

map 对象序列化为:

{"@type":"java.util.HashMap","jsUser":{"@type":"jdk.nashorn.api.scripting.ScriptObjectMirror","value":"{\"name\":\"tom\",\"gender\":\"m\"}"}}

 也就是说,nashorn 对象自定义序列化过程,序列化为一个 json 中的 json 字符串。

在反序列化时将该种字符串反序列化为 ScriptObjectMirror。

思路清楚,但是如何实现呢?

对比了不少 json 库, gson, jackson, apache johnzon, fastjson 等,失望的发现能支持输出类型信息的 json 库都非常少,大部分java库中设计时都有一个静态类型的假设,输出 json 时只输出字段,反序列化时程序员提供 json 字符串及 java类型,库根据 Java 类型确定每个成员映射为何种类型。不得不说这些库花了不少心思,泛型容器什么的都支持的很好,但是场景预设太死了。

最终用上的是国产库 fastjson。

原型代码:

		SerializeConfig serializeConfig = new SerializeConfig();
serializeConfig.put(ScriptObjectMirror.class, new ObjectSerializer() { @Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)
throws IOException {
ScriptObjectMirror som = (ScriptObjectMirror) object;
try {
HashMap<String, Object> so = new HashMap();
so.put("@type", som.getClass().getName());
so.put("value", nashornJson.stringify(som));
serializer.write(so);
// serializer.write(nashornJson.stringify(som));
} catch (UnsupportedConversionException e) { }
}
});
String s2 = com.alibaba.fastjson.JSON.toJSONString(map, serializeConfig, SerializerFeature.WriteClassName);
System.out.println(s2);

序列化时自己构造 @type 和 value 字段。

		ParserConfig config = new ParserConfig();
config.putDeserializer(ScriptObjectMirror.class, new ObjectDeserializer() { @Override
public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
// while(parser.lexer.token() != JSONToken.EOF) {
// System.out.println("TOKEN " + parser.lexer.tokenName() + " VAL " + parser.lexer.stringVal());
// parser.lexer.nextToken();
// } JSONLexer lexer = parser.lexer;
lexer.nextToken(JSONToken.LITERAL_STRING); // "value"
System.out.println(lexer.stringVal());
lexer.nextToken(JSONToken.COLON);
System.out.println(lexer.stringVal());
lexer.nextToken(JSONToken.LITERAL_STRING); // "json of script object mirror"
System.out.println(lexer.stringVal());
String s = lexer.stringVal();
ScriptObjectMirror so;
try {
so = (ScriptObjectMirror) nashornJson.parse(s);
} catch (Exception e) {
return null;
}
lexer.nextToken(JSONToken.RBRACE);
lexer.nextToken();
return (T)so;
} @Override
public int getFastMatchToken() {
return JSONToken.RBRACE;
} });

反序列化时控制 lexer 过程,推进 token。

最终封装好的代码已更新到 d2js。

d2js 中实现 memcached 共享 session 的过程的更多相关文章

  1. 服务器安装Apache+Tomcat+Memcached共享Session的构架设计

    网站集群部署解决计划 一.       计划目标 实现互动留言系统.后台发布系统的高可用性,有效解决高并发量对单台应用服务器的打击,确保应用服务器单点故障不影响系统正常运行. 二.       部署架 ...

  2. 系统时间不一致导致memcached的session不共享

    测试服务器需要做负载均衡,采用的是Nginx+Tomcat. 负载均衡配置成功之后,采用memcached配置session同步.总共4台服务器,三台服务器很顺利的配置成功,最后一台服务器死活不能共享 ...

  3. Nginx + Memcached 实现Session共享的负载均衡

    session共享 我们在做站点的试试,通常需要保存用户的一些基本信息,比如登录就会用到Session:当使用Nginx做负载均衡的时候,用户浏览站点的时候会被分配到不同的服务器上,此时如果登录后Se ...

  4. Tomcat通过Memcached实现session共享的完整部署记录

    对于web应用集群的技术实现而言,最大的难点就是:如何能在集群中的多个节点之间保持数据的一致性,会话(Session)信息是这些数据中最重要的一块.要实现这一点, 大体上有两种方式:一种是把所有Ses ...

  5. 分布式中使用Redis实现Session共享(二)

    上一篇介绍了一些redis的安装及使用步骤,本篇开始将介绍redis的实际应用场景,先从最常见的session开始,刚好也重新学习一遍session的实现原理.在阅读之前假设你已经会使用nginx+i ...

  6. 【荐】PHP Session和Cookie,Session阻塞,Session垃圾回收,Redis共享Session,不推荐Memcached保存Session

    什么是 Session 在 web 应用开发中,Session 被称为会话.主要被用于保存某个访问者的数据. 由于 HTTP 无状态的特点,服务端是不会记住客户端的,对服务端来说,每一个请求都是全新的 ...

  7. 分布式中使用Redis实现Session共享(一)

    上一篇介绍了如何使用nginx+iis部署一个简单的分布式系统,文章结尾留下了几个问题,其中一个是"如何解决多站点下Session共享".这篇文章将会介绍如何使用Redis,下一篇 ...

  8. 分布式Session共享(二):tomcat+memcached实现session共享

    一.前言 本文主要测试memcached实现session共享的实现方式,不讨论如何让nginx参与实现负载均衡等. 二.环境配置 本测试在Window下进行 name version port To ...

  9. 【转】centos安装memcached+php多服务器共享+session多机共享问题

    参考博文: centos安装memcached 源码安装 Yum安装Memcache Memcached内存分配优化及使用问题 <转>php+memcached 实现session共享 P ...

  10. 分布式中使用Redis实现Session共享(转)

    上一篇介绍了如何使用nginx+iis部署一个简单的分布式系统,文章结尾留下了几个问题,其中一个是"如何解决多站点下Session共享".这篇文章将会介绍如何使用Redis,下一篇 ...

随机推荐

  1. Devfreq Bus Dcvs

    一.引言 计算机的世界里,CPU任务分为CPU bound和IO bound.而实际场景下往往是两者混合型任务.针对性能的优化,普遍关注点都在CPU上(不论是CPU的频点和CPU的选核), 往往忽略对 ...

  2. WPF-超市管理系统

    1. 新建 WPF APP (net framework )项目

  3. golang中使用多线程和channel通道

    package controller import ( "context" "github.com/gogf/gf/v2/os/grpool" "sy ...

  4. .NET 7+Vue 3 开源仓库管理系统 ModernWMS

    前言 本系统的设计目标是帮助中小企业乃至大型企业实现仓库操作的自动化与数字化,从而提升工作效率,降低成本,并最终实现业务增长.项目采用 Vue 3 + TS + .NET 7 等前沿框架进行开发,为企 ...

  5. 云原生周刊:Kubernetes v1.28 新特性一览 | 2023.8.14

    推荐一个 GitHub 仓库:Fast-Kubernetes. Fast-Kubernetes 是一个涵盖了 Kubernetes 的实验室(LABs)的仓库.它提供了关于 Kubernetes 的各 ...

  6. 一文彻底弄懂并解决Redis的缓存雪崩,缓存击穿,缓存穿透

    缓存雪崩.缓存击穿.缓存穿透是分布式系统中使用缓存时,常遇到的三类问题,都会对系统性能和稳定性产生严重影响.下面将详细介绍这三者的定义.产生原因.危害以及常见的解决方案. 1. 缓存雪崩 1.1 定义 ...

  7. A星、Floyod、Bellman-Ford

    A 星算法 A 星和 Dijkstra 算法唯一区别在于堆中排序的依据.distance 数组仍然保存实际代价,预估代价只影响堆的弹出顺序. Dijkstra 根据源点到当前点的实际代价进行排序. A ...

  8. CSS动画效果(炫酷登录页面)

    1.整体效果 https://mmbiz.qpic.cn/sz_mmbiz_gif/EGZdlrTDJa6ibiceejK9loT70yREYASOhuSRaI6vQtQ42zN48oafaWDzdn ...

  9. C语言数据类型和变量

    目录 1.数据类型介绍 1.1字符型 1.2整形 1.3浮点型 1.4布尔类型 1.5各种数据类型长度 1.5.1sizeof操作符 1.5.2数据类型长度 1.5.3 sizeof中表达式不计算 2 ...

  10. 【小记】Docker容器间SSH公钥自动交换实现免密登录的一次尝试

    咋想到这茬了 最近开始忙毕设的事儿了,想部署个伪分布式的Spark + Hadoop集群来进行测试.思来考去,最终咱把目光放在了Docker上. 盘了两天,发现这玩意意外的有趣,镜像构建好后开箱即用, ...