Rhino 使用

Rhino 环境准备

从 Mazilla 网站上下载 Rhino 引擎(本文撰写基于最新的版本 Rhino-1.7R3),下载地址为 http://www.mozilla.org/rhino/。将软件包解压,可以得到 Rhino 源代码、文档、测试代码、样例以及一些小工具,利用这些我们便可以通过多种方式执行 JavaScript 脚本。

使用交互模式调用 JS 解释器

  1. 进入交互模式

    进入交互模式有两种方式:使用 js.jar 文件实现和使用 org.mozilla.javascript.tools.shell 实现。

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

    或切换到 tools 编译后目录,输入 java org.mozilla.javascript.tools.shell.Main,同样可以进入带提示符 js> 的命令模式。

  2. 加载 JavaScript 文件

    创建简单的 JavaScript 文件 tools.js,其代码如下:

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

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

  3. 测试 JavaScript 代码运行

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

  4. 退出交互模式

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

Java 嵌入开发

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

  1. 引入 Rhino JavaScript 工具包

    在您的 Java 项目中使用 Rhino JavaScript 引擎,首先要做的工作是要将其引入到您的项目中,所需要类都在 org.mozilla.javascript命名空间下,示例如下:

     import org.mozilla.javascript.Context; import org.mozilla.javascript.Scriptable;

  2. 进入上下文

    在导入 Rhino JavaScript 的 Java 包之后,需要创建并进入 Context。本步骤的作用在于构造 JavaScript 的运行环境,Context 中储存了脚本执行的全局环境信息,示例代码如下:

     Context cx = Context.enter();

    构造 JavaScript 的运行环境非常的简单,只需要调用 Java 类 Context 的静态方法 enter 即可,而无需对 Context 类进行实例化,该方法将会返回 Context 的一个实例。

  3. 初始化标准对象

    在使用 Rhino 执行脚本之前,必须初始化标准对象(Object,Function 等),示例代码如下:

     Scriptable scope = cx.initStandardObjects();

    作用域是 JavaScript 中一个相当重要的概念,在本步骤初始化的 scope 变量类似于构造了一个全局对象,而在整个运行过程中 JavaScript 的变量都会作为该对象的一部分,在下文中介绍的在 Java 中调用 JavaScript 变量就是通过该对象实现。初始化标准化对象,需要调用上下文实例的 initStandardObjects 方法,执行结果将会返回一个 Scriptable 实例化对象。

  4. 执行 JavaScript 脚本

    当以上准备工作结束后,便可以正常的执行 JavaScript 脚本,示例代码如下:

     Object result = cx.evaluateString(scope, string, error, num, null);

    JavaScript 脚本的执行是使用上下文示例中的 evaluateString 方法,执行脚本字符串 string,当脚本中需要使用其它变量时,会在作用域 scope 中寻找所需要的变量,如果发生异常的话则会报告 error 错误信息和所在的行号 num,正确执行结束后会返回一个 Object 对象的运行结果。

  5. 输出运行的结果

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

     System.out.println(cx.toString(result));

  6. 结束上下文

    结束上下文是每次使用 Rhino 结束后必须要做的工作,它将移除上下文和当前的线程并做垃圾回收。示例代码如下:

     Context.exit();

    在每次进入上下文后您都应该调用它退出方法,因为在使用过程中可能会产生异常,所以通常在调用 Context.enter() 进入上下文之后,将退出操作放入对应的 finally 块中。

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

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

     Context ct = Context.<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: baseline;">enter</span>(); 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); Object result = ct.evaluateString(scope, "test();", null, 1, null); System.out.println(result.toString()); } catch (Exception e) { e.printStackTrace(); } finally{ ct.exit(); }

Java 和 JavaScript 对象相互调用

从根本上讲在 Java 项目中嵌入 JavaScript 脚本引擎,最重要的一点是实现 Java 和 JavaScript 之间的数据共享,而使用 Rhino JavaScript 引擎我们不需要添加任何的代码和实现,便可以使用 Java 和 JavaScript 对象之间相互调用,例如在 JavaScript 脚本中可以十分方便的去调用 Java 的工具包,而在 Java 中又可以十分方便的去调用 JavaScript 脚本中的变量,从而实现二者之间的无缝结合,提高项目的灵活度,下面将从这两个方面去详细介绍实现方式。

  1. 在 JavaScript 脚本中使用 Java 对象

    将 Java 部分代码或者功能实现作为 JavaScript 一部分,以脚本的方式执行,这种方式在极大程度上可以减少用户为解决个别问题而费尽脑筋。在 JavaScript 中可以直接使用 Java 对象,示例代码如下:

     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 代码中直接调用 Java 的输出方法,这种方式可能从感觉上不是很舒服,因为需要明确定义 Java 的命名空间等信息。另外,也可以将 Java 对象转换为 JavaScript 对象,并添加到运行环境中,需要添加额外的代码去实现,这种方式有点像 Java 工具包的导入,示例代码如下:

     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);

  2. 在 Java 中调用 JavaScript 脚本中的变量

    在 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 过程中的某些信息时,请首先考虑该对象。

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

    在前文中我们已经向您展示了如何将 Java 代码以 JavaScript 脚本的方式运行,同样我们也可以将 JavaScript 脚本作为 Java 代码进行实现,这样可以使您的项目复用度极大提高,也将会使您在项目开发过程中更加得心应手,示例代码如下:

     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 -Rhino 使用相关推荐

  1. 使用Javascript Rhino重载Java方法

    我有一个这样的类,我想使用Javascript Rhino覆盖这两种方法,有什么建议吗? 提前致谢!! class MyClass() {public void method1(); public v ...

  2. 【Android】不使用WebView来执行Javascript脚本(Rhino)

    前言 动态执行脚本能有效的降低重要功能硬编码带来的问题,尤其是依赖于第三方的应用,可以通过动态脚本+在线参数(例如友盟在线参数)再不更新应用的情况下升级功能. 声明 欢迎转载,但请保留文章原始出处:) ...

  3. java 画笔跟swing组件_Java学习教程(基础)--Java版本历史(二)

    Java语言自JDK1.0版本以来经历了许多次更新,也在基本程序库中增加了大量的类别和包.从J2SE 1.4开始,Java语言的变动由 Java Community Process(JCP)管理,JC ...

  4. 《深入理解Java虚拟机》-周志明 -第3版-第一章摘记

    第一章讲了java的发展和变迁,在章节末作者讲到了编译openjdk源码和调试源码 java发展史 java的诞生起因史1991年4月,James Gosling博士领导的绿色计划(Green Pro ...

  5. mirai 高效率 QQ 机器人框架

    其他文章可以访问以下链接: https://blog.csdn.net/sxf1061700625/article/details/1201312451 QQ控制树莓派(舵机+摄像头+...)_小锋学 ...

  6. Java版本之前世今生(一)

    Java版本之前世今生(一) 文章目录 Java版本之前世今生(一) **1. Oak 语言** **2. JDK Beta** **3. JDK 1.0** **4. JDK 1.1** **5.J ...

  7. Java 的发展历史1991-2022

    1991–1994 Green Project 此计划最初的目标 是开发一种能够在各种消费性电子产品(如机顶盒.冰箱.收音机等)上运行的程序架构. 作为 Green Project 的一部分,Sun ...

  8. 了解一下,Java 虚拟机

    1.1 - 概述 Java 总述:Java 不仅是一门编程语言,还是一个由一系列计算机软件和规范形成的技术体系,这个技术体系提供了完整的用于软件开发和跨平台部署的支持环境,并广泛应用于 嵌入式系统. ...

  9. 深入理解 Java 虚拟机——走近 Java

    1.1 - 概述 Java 总述:Java 不仅是一门编程语言,还是一个由一系列 计算机软件 和 规范 形成的技术体系,这个技术体系提供了完整的用于软件开发和跨平台部署的支持环境,并广泛应用于 嵌入式 ...

最新文章

  1. oracle cube排序,Oracle rollup cube 用法
  2. win8 远程桌面时提示凭证不工作问题的终极解决办法
  3. Linux:hping高级主机扫描
  4. JFreeChart(四)之线型图
  5. latex-bib参考文献人名特殊字符
  6. php preg_match正则匹配中文-有深意
  7. [流体输配管网] 使用 Matlab 绘制莫迪图
  8. Java or PHP? 谈谈高并发网站的技术选型和架构设计
  9. 群星服务器id不显示,群星代码([群星]求助,领袖特性代号怎么查看啊 NGA玩家社区)...
  10. 模拟电子技术基础笔记(1)
  11. 安卓flash插件_谷歌Chrome 76稳定版正式发布:默认禁用Flash
  12. springMVC注解的意思
  13. Chrome和Chromium的区别
  14. ensp华为防火墙的简单区域划分和配置
  15. 在虚幻引擎5中构建你的首款游戏 - 10[完] - 特效音效镜头震动打包
  16. java和python结合做项目_由浅入深Java+Python结合项目实战
  17. Hopcroft-Carp(有点难)
  18. 一文了解 TKG 如何使用 GPU 资源池
  19. vue3+setup写法
  20. js修改伪元素的属性、styleSheets获取样式表,Failed to read the 'cssRules' property from 'CSSStyleSheet' Cannot acces

热门文章

  1. Altium Designer学习笔记——如何使用模板图纸
  2. 演示LCEDA立创商城原理图和PCB封装转Cadence
  3. 天津软考·项目管理(免费)说明会
  4. R语言使用lm函数构建线性回归模型、使用lrtest包的dwtest函数执行残差自相关检验Durbin–Watson检验(p值大于alpha,不存在残差自相关)
  5. 上海2022年10月月赛丙组 T5:组队竞赛
  6. 解决windows与ubuntu双系统时间不一致的问题
  7. inkscape如何裁剪_科学网—如何在Inkscape图中输入LaTeX公式? - 李金磊的博文
  8. 连连看c语言代码,连连看C语言代码.doc
  9. windows下查看端口占用并终止进程
  10. 一点实用主义的学英语心得