精彩专题推荐:建站之入门课 建站之必修课 建站之关键课 网站价值所在 流量提高专题 css+div 标准 个人网站打造全过程
返回建站学首页
导航:
建站首页 | 网站设计 | 网站开发 | 网站运营 | 网页软件 | 建站指南 | 搜索优化 | 图像处理 | 视频教程 | 书籍教程 | 建站专题
当前位置:首页>网站开发>JSP教程>正文

动态调用动态语言之Java脚本API


来源:不详 时间:07-09-20 点击: 点击这里收藏本文


  注意,清单 4 中没有 JavaScript 代码。Invocable 接口允许 Java 代码调用脚本函数,而无需知道其实现语言。如果脚本引擎无法找到给定名称或参数类型的函数,那么 invokeFunction() 方法将抛出一个 java.lang.NoSuchMethodException。

  Java 脚本 API 并不要求脚本引擎实现 Invocable 接口。实际上,清单 4 中的代码应该使用 instanceof 运算符确保脚本引擎在转换(cast)之前实现了 Invocable 接口。

  通过脚本代码调用 Java 方法

  清单 3 和 清单 4 中的示例展示了 Java 代码如何调用脚本语言中定义的函数或方法。您可能会问:脚本语言中编写的代码是否可以反过来对 Java 对象调用方法呢?答案是可以。清单 5 中的 invokeJavaFromScriptFunction() 方法显示了如何使脚本引擎能够访问 Java 对象,以及脚本代码如何才能对这些 Java 对象调用方法。明确的说,invokeJavaFromScriptFunction() 方法使用脚本引擎的 put() 方法将 HelloScriptingWorld 类的实例本身提供给引擎。当引擎拥有 Java 对象的访问权之后(使用 put() 调用所提供的名称),eval() 方法脚本中的脚本代码将使用该对象。

  清单 5. invokeJavaFromScriptFunction 和 getHelloReply 方法

private static void invokeJavaFromScriptFunction(ScriptEngine engine)
throws ScriptException
{
engine.put("helloScriptingWorld", new HelloScriptingWorld());
engine.eval(
"println('Invoking getHelloReply method from JavaScript...');" +
"var msg = helloScriptingWorld.getHelloReply(vJavaScript');" +
"println('Java returned: ' + msg)"
);
}

/** Method invoked from the above script to return a string. */
public String getHelloReply(String name) {
return "Java method getHelloReply says, 'Hello, " + name + "'";
}

  清单 5 中的 eval() 方法调用中所包含的 JavaScript 代码使用脚本引擎的 put() 方法调用所提供的变量名称 helloScriptingWorld 访问并使用 HelloScriptingWorld Java 对象。清单 5 中的第二行 JavaScript 代码将调用 getHelloReply() 公有 Java 方法。getHelloReply() 方法将返回 Java method getHelloReply says, 'Hello, <parameter>' 字符串。eval() 方法中的 JavaScript 代码将 Java 返回值赋给 msg 变量,然后再将其打印输出给控制台。

  Java 对象转换

  当脚本引擎使运行于引擎环境中的脚本能够使用 Java 对象时,引擎需要将其封装到适用于该脚本语言的对象类型中。封装可能会涉及到一些适当的对象-值转换,比如说允许 Java Integer 对象直接在脚本语言的数学表达式中使用。关于如何将 Java 对象转换为脚本对象的研究是与各个脚本语言的引擎特别相关的,并且不在本文的讨论范围之内。但是,您应该意识到转换的发生,因为可以通过测试来确保所使用的脚本语言执行转换的方式符合您的期望。

  ScriptEngine.put 及其相关 get() 方法是在运行于脚本引擎中的 Java 代码和脚本之间共享对象和数据的主要途径。(有关这一方面的详细论述,请参阅本文后面的 Script-execution scope 一节。)当我们调用引擎的 put() 方法时,脚本引擎会将第二个参数(任何 Java 对象)关联到特定的字符串关键字。大多数脚本引擎都是让脚本使用特定的变量名称来访问 Java 对象。脚本引擎可以随意对待传递给 put() 方法的名称。比如说,JRuby 脚本引擎让 Ruby 代码使用全局 $helloScriptingWorld 对象访问 helloScriptingWorld,以符合 Ruby 全局变量的语法。

  脚本引擎的 get() 方法检索脚本环境中可用的值。一般而言,Java 代码通过 get() 方法可以访问脚本环境中的所有全局变量和函数。但是只有明确使用 put() 与脚本共享的 Java 对象才可以被脚本访问。

  外部脚本在运行着的应用程序中访问和操作 Java 对象的这种功能是扩展 Java 程序功能的一项强有力的技巧。(第 2 部分将通过示例研究这一技巧)。

  运行 HelloScriptingWorld 应用程序

  您可以通过下载和构建源代码来运行 HelloScriptingWorld 应用程序。此 .zip 中文件含有一个 Ant 脚本和一个 Maven 构建脚本,可以帮助大家编译和运行示例应用程序。请执行以下步骤:

  ·下载 .zip 文件。
  ·创建一个新目录,比如说 java-scripting,并将步骤 1 中所下载的文件解压到该目录中。
  ·打开命令行 shell 并转到该目录。
  ·运行 ant run-hello 命令。

  您应该可以看到类似于清单 6 的 Ant 控制台输出。注意,defineScriptFunction() 函数没有产生任何输出,因为它虽然定义了输出但是却没有调用 JavaScript 函数。

   清单 6. 运行 HelloScriptingWorld 时的输出

Calling invokeHelloScript...
Hello from JavaScript

Calling defineScriptFunction...

Calling invokeScriptFunctionFromEngine...
Hello, World!

Calling invokeScriptFunctionFromJava...
Hello, from Java

Calling invokeJavaFromScriptFunction...
Invoking getHelloReply method from JavaScript...
Java returned: Java method getHelloReply says, 'Hello, JavaScript'

  Java 5 兼容性

  Java SE 6 引入了 Java 脚本 API,但是您也可以使用 Java SE 5 运行此 API。只需要提供缺少的 javax.script 包类的一个实现即可。所幸的是,Java Specification Request 223 参考实现中含有这个实现(请参阅 参考资料 获得下载链接。)JSR 223 对 Java 脚本 API 做出了定义。

  如果您已经下载了 JSR 223 参考实现,解压下载文件并将 script-api.jar、script-js.jar 和 js.jar 文件复制到您的类路径下。这些文件将提供脚本 API、JavaScript 脚本引擎接口和 Java SE 6 中所附带的 JavaScript 脚本引擎。
9 7 3 1 2 3 4 5 4 8 :

  把此文章收藏到:          
广而告之
文章搜索
  • Google JZxue.Com

关于我们 | 联系我们 | 友情链接 | 网站地图
Copyright © 2005 - 2006 建站学 All rights reserved.