3. 从 Java 代码调用脚本
从脚本调用 Java 对象仅仅完成了一半的工作:Java 脚本环境也提供了从 Java 代码调用脚本的功能。这只需要实例化一个 ScriptEngine 对象,然后加载和评估脚本,如清单 5 所示:
清单 5. Java 平台的脚本调用
26. import java.io.*;
27. import javax.script.*;
28.
29. public class App
30. {
31. public static void main(String[] args)
32. {
33. try
34. {
35. ScriptEngine engine =
36. new ScriptEngineManager().getEngineByName(“javascript”);
37. for (String arg : args)
38. {
39. FileReader fr = new FileReader(arg);
40. engine.eval(fr);
41. }
42. }
43. catch(IOException ioEx)
44. {
45. ioEx.printStackTrace();
46. }
47. catch(ScriptException scrEx)
48. {
49. scrEx.printStackTrace();
50. }
51. }
52. }
eval() 方法也可以直接操作一个 String,所以这个脚本不一定必须是文件系统的一个文件 — 它可以来自于数据库、用户输入,或者甚至可以基于环境和用户操作在应用程序中生成。
4. 将 Java 对象绑定到脚本空间
仅仅调用一个脚本还不够:脚本通常会与 Java 环境中创建的对象进行交互。这时,Java 主机环境必须创建一些对象并将它们绑定,这样脚本就可以很容易找到和使用这些对象。这个过程是 ScriptContext 对象的任务,如清单 6 所示:
清单 6. 为脚本绑定对象
53.
54.
55. import java.io.*;
56. import javax.script.*;
57.
58. public class App
59. {
60. public static void main(String[] args)
61. {
62. try
63. {
64. ScriptEngine engine =
65. new ScriptEngineManager().getEngineByName(“javascript”);
66.
67. for (String arg : args)
68. {
69. Bindings bindings = new SimpleBindings();
70. bindings.put(“author”, new Person(“Ted”, “Neward”, 39));
71. bindings.put(“title”, “5 Things You Didn’t Know”);
72.
73. FileReader fr = new FileReader(arg);
74. engine.eval(fr, bindings);
75. }
76. }
77. catch(IOException ioEx)
78. {
79. ioEx.printStackTrace();
80. }
81. catch(ScriptException scrEx)
82. {
83. scrEx.printStackTrace();
84. }
85. }
86. }
访问所绑定的对象很简单 — 所绑定对象的名称是作为全局命名空间引入到脚本的,所以在 Rhino 中使用 Person 很简单,如清单 7 所示:
清单 7.
87.
88.
89. println(“Hello from inside scripting!”)
90.
91. println(“author.firstName = ” + author.firstName)
您可以看到,JavaBeans 样式的属性被简化为使用名称直接访问,这就好像它们是字段一样。