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. 全网最适合入门的面向对象编程教程:53 Python 字符串与序列化-字符串与字符编码

    全网最适合入门的面向对象编程教程:53 Python 字符串与序列化-字符串与字符编码 摘要: 在 Python 中,字符串是文本的表示,默认使用 Unicode 编码,这允许你处理各种字符集,字符编 ...

  2. Ant-Design-Vue 图片上传

    功能演示 我们要实现的功能如下,有两个按钮,点击第一个按钮选择文件,选择文件后点击第二个按钮上传到服务器. 功能需求: 只允许上传 png.jpg/jpeg 格式的图片 没有上传图片时显示占位图 选择 ...

  3. CentOS7 安装配置笔记 v2

    1.通过镜像安装 CentOS72.安装 wget 下载工具3.修改镜像地址4.安装 nano 文本编辑工具5.安装 dotnet core6.安装vsftpd7.设置 firewalld8.为 do ...

  4. Android Qcom USB Driver学习(二)

    BC v1.2充电规范 Battery Charging Specification USB port 如何识别不同的Charger类型 USB Charger类型 USB_SDP_CHARGER P ...

  5. blocks 单调栈、单调队列题解

    blocks题解: 1.题面: 2.分析: 题意大概就是说,找一段最长的区间,并且这段区间的平均值>=k,那么我们可以对他的每一个值减去k,最终求和>=0即可. 那我们需要对每个可能的左端 ...

  6. Gitlab私有存储库支持SourceLink 调试之使用proxy方式

    前情概要 在 让你发布的nuget包支持源代码调试#为gitlab的私有源代码项目提供支持 小节中有介绍到如何让gitlab的私有存储库支持SourceLink. 其中有一个方法是说在vs中打开web ...

  7. 函数计算平台 OpenFunction 在自动驾驶领域的应用

    嘉宾 | 霍秉杰 整理 | 王新 出品 | CSDN 云原生 2022 年 5 月 10 日,在 CSDN 云原生系列在线峰会第 4 期"ApacheSkyWalking 峰会"上 ...

  8. 万星开源项目:System Design Primer - 学习系统设计的必备指南

    GitHub 链接:https://github.com/donnemartin/system-design-primer 什么是 System Design Primer? System Desig ...

  9. Linux Shell简介

    目录 Shell是什么 基本介绍 用Shell编写HelloWorld Shell是什么 Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以 ...

  10. 基于Java+SpringBoot心理测评心理测试系统功能实现八

    一.前言介绍: 1.1 项目摘要 心理测评和心理测试系统在当代社会中扮演着越来越重要的角色.随着心理健康问题日益受到重视,心理测评和心理测试系统作为评估个体心理状态.诊断心理问题.制定心理治疗方案的工 ...