天天看点

用 Rhino/Nashorn 代替第三方 JSON 转换库(第三版)

无须其他第三方包,只是依赖于 Java 自带的 JVM 自带的 Rhino/Nashorn 引擎提供 js/json 的服务。主要的两个类是 JsEngineWrapper、JsonHelper,它们的继承关系是 JsEngineWrapper 派生了 JsonHelper。

JsEngineWrapper 对默认的 ScriptEngine 进行封装,提供下列方法:

提供兼容 rhino/nashron 的 js 引擎

提供 加载 js 文件的 load(*.js) 方法。重载 load(class, *.js) 方法可以加载指定类位置的 js 文件;

封装 js 代码的方法 eval 方法(自动捕获 ScriptException 异常),并可以传入 Class 参数转换 js 所返回的类型为你期望的目标类型;

封装 call/put/get 等方法,详细见例子的应用,都是基于原 ScriptEngine 的简单封装。

兼容 rhino/nashron

创建 js 引擎工厂,支持 java 6/7 的 rhino 和 java 8 的 nashorn,源码如下:

可想而知,ScriptEngine 是消耗资源比较大的对象,一般建议单例使用。

加载 js 文件

对 js 引擎执行 js 语句

js 语句是任意合法 js 语句,可以是一大串 js 代码、变量名或表达式。一般情况下原生 eval() 返回 Object,不过我们可以强类型转换之。注意 js 的 number 为 java 的 double。直接使用 double 不太好使,将其转换为 int。

封装 call/put/get 等方法

json 转为 java 对象的工具类,反之亦提供 java 转换为 js 的方法。该类继承自 JsEngineWrapper。

js 引擎的 eval() 不支持直接返回任何值,如 eval(“{a:1}”)–>null,必须加变量,例如 执行 eval(“ar xx = {…};”) 方可,故我们有 accessJsonMember 方法:

String/Number/Boolean 类型需要开发者自己传参数调用,而较复杂的 List/Map 则提供了获取方法,用法如下:

既然有 js–>java 的方法那么亦有 java–>json 的方法:stringify(key)、stringifyObj(obj)。

还有一些静态的方法也是能做到 stringify 之目的,时间关系这里就不展开了。

Bean2Json 是通过 js 的反射把 bean 转换为 json 的。当然 java 也可以写 反射不过相当的麻烦所以用 js 偷懒了……

TODO :JDK 8 下的测试。

这个思路我很早就有,中间也写过几个版本,总是不太令自己满意,所以改来改去(走了一些弯路其实思路还是很简单的)。以后不打算折腾了(当然还是欢迎您给意见我)。参见以前的:

<a href="http://blog.csdn.net/zhangxin09/article/details/51810804">《用 Rhino/Nashorn 代替第三方 JSON 转换库》</a>

<a href="http://blog.csdn.net/zhangxin09/article/details/6401031">《使用 Rhino 作为 Java 的 JSON 解析/转换包》</a>