Rhino初试

2019-06-21  本文已影响0人  沐泠LHY

整理自一篇CSDN博客
Rhino 是开源的 JavaScript 引擎,是完全基于 Java 实现,几乎可以使用 JavaScript 完成 Java 所有的工作,而且支持将 JavaScript 编译成 Java 字节码。在 Rhino 环境中既可以使用 JavaScript 的工具,同时也可以非常简单的使用 Java 的工具。

Rhino可以以jar形式导入项目,也可以在控制台运行
jar下载链接

控制台使用Rhino

进入交互模式

打开控制台,并切换 rhino.jar 文件所在的目录,输入java -jar rhino.jar命令,便会出现解释器的版本信息,并进入带提示符 js> 的命令模式。

加载 JavaScript 文件

创建tools.js,其代码如下:

var tools = {};
tools.testPlus = function(num1 , num2){
     return num1 + num2;
}

在命令行中输入 load("C:/tools.js"),完成 tools.js 文件的加载。注意在此处"/"和"\"是有区别的,不能换用。

测试 JavaScript 代码运行

在命令行中输入tools.testPlus(1,2),显示执行结果为 3,证明 JavaScript 代码运行成功。

退出交互模式

退出交互模式可以用Ctrl+Z(Windows 系统)或Ctrl+D(Linux 或 Unix 系统),也可以调用quit()方法退出。

嵌入java或android项目

本部分将向您介绍如何将 Rhino JavaScript 引擎嵌入到你的项目中,从而使你的应用程序增加脚本的支持,提高灵活度。简单而言,Rhino 的作用在于构造一个 JavaScript 运行所需要的运行环境,亦即下面所用的关键词上下文 Context。

在项目中导入的Rhino的jar

下载链接见为首

引入构建javascript运行环境所需类
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
...
创建上下文

创建JavaScript运行的Context。本步骤的作用在于构造 JavaScript 的运行环境,Context 中储存了脚本执行的全局环境信息,示例代码如下:
Context cx = Context.enter();

初始化标准对象

在使用 Rhino 执行脚本之前,必须初始化标准对象(Object,Function 等)
Scriptable scope = cx.initStandardObjects();
作用域(scope)是 JavaScript 中一个相当重要的概念,在本步骤初始化的 scope 变量类似于构造了一个全局对象,而在整个运行过程中 JavaScript 的变量都会作为该对象的一部分,在下文中介绍的在 Java 中调用 JavaScript 变量就是通过该对象实现。

执行 JavaScript 脚本

当以上准备工作结束后,便可以执行 JavaScript 语句了,示例代码如下:
Object result = cx.evaluateString(scope,source,sourcename,lineon,null);
JavaScript 脚本的执行可以使用上下文示例的 evaluateString 方法,执行脚本字符串source,当脚本中需要使用其它变量时,会在作用域 scope 中寻找,sourcename(脚本名称)和lineon主要为了方便调试,比如若有报错信息,会附带脚本名称和错误所在行数(根据lineon和脚本字符串计算出),正确执行结束后会返回一个 Object 对象的运行结果。

输出运行的结果

JavaScript 没有独立的输入输出方法,必须借助于宿主环境的输入输出方法,这里使用 Java 的输出机制 System.out.println 方法,示例代码如下:
System.out.println(cx.toString(result));

结束上下文

结束上下文是每次使用 Rhino 结束后必须要做的工作,它将移除上下文和当前的线程并做垃圾回收。示例代码如下:
Context.exit();
在每次进入上下文后您都应该调用它退出。由于在使用过程中可能会产生异常,最好将退出操作放入对应的 finally 块中。

Java 和 JavaScript 交互

从根本上讲在 Java 项目中嵌入 JavaScript 脚本引擎,最重要的一点是实现 Java 和 JavaScript 之间的数据共享。Rhino为我们提供了强大的Java 和 JavaScript 交互的方法。

JavaScript中使用Java的功能

将一部分功能用 Java 实现,并在JavaScript中调用,可以方便解决java转换到JavaScript产生的个别问题,示例代码如下:

Context ct = Context.enter();
Scriptable scope = ct.initStandardObjects();
String str = "var test={};";
str += "test.call=function(){return 'Successful!';};";
str += "java.lang.System.out.println(test.call())";
ct.evaluateString(scope, str, null, 1, null);

可以在JavaScript使用Rhino提供的importPackage和importClass,详见文末链接

将Java对象共享到JavaScript

可以将 Java 对象转换为 JavaScript 对象,并用putProperty方法添加到运行环境中,示例代码如下:

Context ct = Context.enter();
Scriptable scope = ct.initStandardObjects();
Object out = Context.javaToJS(System.out, scope);
ScriptableObject.putProperty(scope, "out", out);
ct.evaluateString(scope, "out.println('Successful!')", null, 1, null);
在 Java 中获取 JavaScript 脚本中的变量

可以用于获取脚本运行过程中的一些临时信息变量,示例代码如下:

Context ct = Context.enter();
Scriptable scope = ct.initStandardObjects();
ct.evaluateString(scope, "var test = 'Successful';", null, 1, null);
Object jsObject = scope.get("test" , scope);
if (jsObject == Scriptable.NOT_FOUND) {
   System.out.println("test is not defined.");
} else {
   System.out.println("test is " + Context.toString(jsObject));
}

在上述的示例代码中,我们同样用到了 scope 变量,这个是 JavaScript 运行时的全局变量,你可以将它理解成为一个容器,里面包含了 JavaScript 运行过程中的所有信息,所以如果你希望取得 JavaScript 过程中的某些信息,应首先考虑该对象。

在 Java 中调用 JavaScript 脚本中的函数

在前文中介绍了如何在 JavaScript 脚本运行Java函数,同样我们也可以在Java代码中运行JavaScript中的函数,示例代码如下:

Context ct = Context.enter();
Scriptable scope = ct.initStandardObjects();
ct.evaluateString(scope,"function test(name){return 'Successful!'+name;}", null, 1, null);
Object functionObject = scope.get("test" , scope);
if (!(functionObject instanceof Function)) {
    System.out.println("test is undefined or not a function.");
} else {
    Object testArgs[] = {"Ceven"};
    Function test = (Function)functionObject;
    Object result = test.call(ct, scope, scope, testArgs);
    System.out.println(Context.toString(result));
}

另附:

在运行环境中导入 JavaScript 工具包

在系统开发过程中,我们经常会使用一些 JavaScript 工具包,如加密工具包等。而使用 Rhino 导入工具包也是非常的简单方便,只需要将工具包文件中的内容以字符的形式在上下文中运行,以后便可以在对应的作用域中直接使用。示例代码如下:

Context ct = Context.enter();
Scriptable scope = ct.initStandardObjects();
String filename=System.getProperty("user.dir")+"/demo/test.js";
try {
    LineNumberReader reader = new LineNumberReader(new 
    FileReader(filename));
    String temp = null;
    StringBuffer sb = new StringBuffer();
    while((temp = reader.readLine()) != null){
         sb.append(temp).append("\n");
    }
    ct.evaluateString(scope, sb.toString(), null, 1, null);
     //test()是test.js里的方法,此处无关紧要,略去
    Object result = ct.evaluateString(scope, "test();", null, 1, null);
    System.out.println(result.toString());
} catch (Exception e) {
    e.printStackTrace();
} finally{
    ct.exit();
}

最后,附带Rhino的文档链接

上一篇下一篇

猜你喜欢

热点阅读