美文网首页
Rhino初试

Rhino初试

作者: 沐泠LHY | 来源:发表于2019-06-21 16:13 被阅读0次

    整理自一篇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的文档链接

    相关文章

      网友评论

          本文标题:Rhino初试

          本文链接:https://www.haomeiwen.com/subject/xlfuqctx.html