zoukankan      html  css  js  c++  java
  • d2js 中实现 memcached 共享 session 的过程

    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。

  • 相关阅读:
    1. C/C++项目一
    3. C/C++笔试面试经典题目三
    1. C/C++笔试面试经典题目一
    Win7下C/C++跨平台开发工具IDE的安装之Eclipse-CDT
    Win7下C/C++跨平台开发工具IDE的安装之CodeBlocks
    css
    form表单,选择器
    html介绍
    元类
    事务、视图、触发器、存储过程、函数、数据库的备份
  • 原文地址:https://www.cnblogs.com/inshua/p/8135192.html
Copyright © 2011-2022 走看看