芯学苑专注java培训十年

当前位置  |首页新闻中心 行业资讯 Java Scripting API 使用示例

Java Scripting API 使用示例

来源:2017-09-16关键词: 示例

Java Scripting API 包含一组类和接口,在 javax.script 包中定义。这是一个相对比较小的 Java 包,以 ScriptEngineManager 类作为起点。一个 ScriptEngineManager 对象可以通过 JAR 文件服务发现机制来查找脚本引擎,而实例化 ScriptEngine 对象的解析脚本使用专门的脚本语言编写。

1505542595108100.jpg

Nashorn 引擎是 Java SE 开发工具包(JDK)自带的默认 ECMAScript (JavaScript)引擎。Nashorn 引擎是 Oracle 使用纯 Java 开发的,是 OpenJDK 项目的一部分。

 

虽然 Nashorn 是 Java Scripting API 默认使用的 ECMAScript 引擎,但你也可以使用其他兼容 JSR 223 的脚本引擎,或者你可以实现自己的引擎。该文档不涉及脚本引擎的实现方法,但最最基础的级别,你必须实现 javax.script.ScriptEngine 和 javax.script.ScriptEngineFactory 接口。抽象类 javax.script.AbstractScriptEngine 提供了很多默认 ScriptEngine 接口的方法实现。

 

使用 Java Scripting API 的步骤:

 

1、创建一个 ScriptEngineManager 对象.

2、从管理器对象中获取 ScriptEngine 对象

3、使用脚本引擎的 eval() 方法来执行脚本

 

下面我们提供了几个例子来展示如何使用 Java Scripting API。为了让例子尽可能的简单,我们没有对执行过程中的异常进行处理。Java Scripting API 的异常有受检查异常和运行时异常两种,这些异常必须进行正确处理。在每个例子中,ScriptEngineManager 类的实例是通过 Nashorn 引擎的 getEngineByName() 方法来获取的。如果指定名称的引擎不存在,该方法会返回 null 。

 

注意:每个 ScriptEngine 对象都有它独有的变量作用域。要使用多个变量作用域请看 Example 8.

 

示例 1 —— 执行脚本语句

 

在这个例子中,调用脚本引擎实例的 eval() 方法来执行以字符串标识的 JavaScript 代码。

 

执行脚本语句.jpg

 

示例 2 —— 执行脚本文件

在这个例子中, eval() 方法传递了一个 FileReader 对象作为参数,从 scripts.js 文件中读取 JavaScript 代码。通过封装不同的输入流对象作为 reader 来实现从文件、URL 或者其他资源中执行脚本。

 

执行脚本文件.png

 

示例 3 —— 输出 Java 对象作为全局变量

在这个例子中,我们创建了一个 File 对象并通过 put() 方法暴露给引擎作为一个名为 file 的全局变量。然后在 JavaScript 代码中调用 eval() 方法就可以访问该变量并调用 getAbsolutePath() 方法。

 

注意:

 

作为变量的 Java 对象的字段访问和方法调用语法取决于脚本语言。该例子使用 JavaScript 语法,和 Java 的类似。

 

输出Java对象作为全局变量.png

 

示例 4 —— 调用脚本函数

本例中在 JavaScript 代码中调用 eval() 方法,定义了一个包含单个参数的函数。然后创建 Invocable 对象,并使用其方法 invokeFunction() 来调用这个函数。

 

注意:

 

并非所有的脚本引擎都实现了 Invocable 接口。本例中使用 Nashorn 引擎,可以在脚本中调用之前引擎已经定义的函数。

 

调用脚本函数.png

 

示例 5 —— 调用脚本对象的方法

本例中在 JavaScript 代码中调用 eval() 方法定义包含一个方法的对象。该对象在脚本中通过脚本引擎的 get() 方法暴露给 Java 应用,然后创建一个 Invocable 对象,并通过 invokeMethod() 方法调用对象的方法。

 

注意:

 

并非素有的脚本引擎都实现了 Invocable 接口。本例中使用 Nashorn 引擎,可以调用引擎之前已经定义的脚本方法。

 

调用脚本对象的方法.png

 

示例 6 —— 实现一个包含脚本函数的 Java 接口

本例中在 JavaScript 代码中调用 eval() 方法来定义一个函数。然后创建一个 Invocable 对象,并通过其getInterface() 方法来创建一个 Runnable 接口对象。

接口的方法在脚本函数中实现,这是通过函数名称匹配的方式实现的(本例中 run() 函数用来实现接口对象的 run() 方法)。最后,启动一个新的线程来运行脚本函数。

 

 

实现一个包含脚本函数的 Java 接口.png

 

示例 7 —— 在脚本对象方法中实现 Java 接口

本例中在 JavaScript 代码中调用 eval() 方法来定义一个包含单个方法的对象。该对象在脚本中通过 get() 方法暴露给 Java 应用。然后创建一个 Invocable 对象并通过其 getInterface() 方法来创建一个 Runnable 接口对象。

该接口的方法实现是在脚本对象中相同匹配名称的函数中(本例中对象的 run 方法对应接口的 run 方法的实现)。最后启动一个新线程来运行脚本对象的方法。

 

在脚本对象方法中实现 Java 接口.png

 

示例 8 —— 使用多个变量作用域

本例中脚本引擎的 put() 方法用来设置 x 变量值为 “hello” 字符串对象。紧接着 eval() 方法用来打印默认作用域下的变量值。然后定义一个不同的脚本上下文,并在其作用域下设置相同变量为不同的值(“world” 字符串)。

最后在新的脚本上下文中答应该变量,显示为不同的值。

 

单一的作用域是 javax.script.Bindings 接口的实例。这个接口继承自 java.util.Map 接口。一个作用域相当于是成对的名称和值的列表,其中名称不能为空。javax.script.ScriptContext 接口通过为每个作用域关联一个 Bindings 对象来实现对多个作用域的支持。

默认情况下,每个脚本应用有自己独立的上下文。默认的脚本上下文至少有一个作用域,这是通过静态属性 ENGINE_SCOPE 来定义的。脚本上下文可以通过 getScopes() 方法来实现对不同作用域的支持。

 

使用多个变量作用域.png