博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
d2js 中实现 memcached 共享 session 的过程
阅读量:4539 次
发布时间:2019-06-08

本文共 3078 字,大约阅读时间需要 10 分钟。

基于 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
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
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 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。

转载于:https://www.cnblogs.com/inshua/p/8135192.html

你可能感兴趣的文章
PAT甲级——A1130 Infix Expression【25】
查看>>
PAT甲级——A1126 Eulerian Path【30】
查看>>
PAT甲级——A1127 ZigZagging on a Tree【30】
查看>>
PAT甲级——A1010 Radix
查看>>
PAT甲级——A1012 The Best Rank
查看>>
左神算法书籍《程序员代码面试指南》——1_07生成窗口最大值数组
查看>>
左神算法进阶班6_1LFU缓存实现
查看>>
力扣算法题—460LFU缓存
查看>>
左神算法进阶班7_1求最大异或和的子数组
查看>>
左神算法进阶班7_2换钱组合数
查看>>
每天逛逛
查看>>
PAT甲级——【牛客练习A1004】
查看>>
PAT甲级——【牛客A1005】
查看>>
PAT甲级——A1001A+BFormat
查看>>
PAT甲级——A1002 A+B for Polynomials
查看>>
PAT甲级——A1003Emergency
查看>>
左神算法进阶班6_2字符串运算公式
查看>>
PAT甲级——A1004 Counting Leaves
查看>>
左神算法书籍《程序员代码面试指南》——1_01设计一个有getMin功能的栈
查看>>
左神算法进阶班8_1数组中累加和小于等于aim的最长子数组
查看>>