本文将分以下几个小节来学习:
脚本与java数据传递
脚本语言支持API的一个很大的优势在于它规范了Java语言与脚本语言之间的交互方式,使Java语言编写的程序可以和脚本之间进行双向的方法调用和数据传递。
数据传递是通过Bindings接口来实现的,其实Bindings对象就是一个简单的哈希表,用来存放和获取所需的共享数据。所有数据都对应这个哈希表中的一个条目,是简单的键值对。
ScriptEngine对象中有个默认的Bindings对象,提供了put和get方法对脚本引擎中特定作用域的数据传递。
Demo:
package net.oseye;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class ScriptTest {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager factory=new ScriptEngineManager();
ScriptEngine se=factory.getEngineByName("JavaScript");
se.put("name", "kevin");
se.eval("var msg='my name is '+name;println(msg);");
System.out.println(se.get("msg"));
}
}
输出:
my name is kevin my name is kevin
ScriptEngine对象通过put方法向脚本默认Bindings对象添加键为"name",值为"kevin"的字符串,然后eval中可直接使用name。在java中可通过ScriptEngine对象的get方法获取到脚本的变量msg。这样就完成了Java和脚本预言的双向数据传递。
在大多说情况下使用ScriptEngine的默认Bindings对象就足够的,但如果不够,你可以使用自己的Bindings对象。可以使用ScriptEngine对象的creteBindings方法或new一个javax.script.SimpleBindings对象来创建。Demo:
package net.oseye;
import javax.script.*;
public class ScriptTest {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager factory=new ScriptEngineManager();
ScriptEngine se=factory.getEngineByName("JavaScript");
// Bindings bindings=new SimpleBindings();
Bindings bindings=se.createBindings();
bindings.put("name", "kevin");
se.eval("var msg='my name is '+name;println(msg);",bindings);
System.out.println(bindings.get("msg"));
}
}
脚本执行上下文
脚本引擎通过ScriptContext接口对象获取与脚本执行相关的信息,也允许开发人员通过此对象来配置脚本引擎的行为。
- 输入与输出
在默认情况下,脚本的输入和输出都发生在标准的控制台中,但可以用ScriptContext接口对象让脚本在执行中用java.io.Reader对象来输入,用java.io.Writer对象来输出。例如把脚本的输出写入到一根文件中,就可以利用setWriter方法把脚本输出重定向到一个文件中。package net.oseye; import java.io.*; import javax.script.*; public class ScriptTest { public static void main(String[] args) throws ScriptException, IOException { ScriptEngineManager factory=new ScriptEngineManager(); ScriptEngine se=factory.getEngineByName("JavaScript"); ScriptContext sc=se.getContext(); sc.setWriter(new FileWriter("out.txt")); se.eval("println('test')"); } }
- 自定义属性
ScriptContext也有获取和设置属性的方法,这点类似SeverletContext,即setAttribute和getAttribute。package net.oseye; import java.io.*; import javax.script.*; public class ScriptTest { public static void main(String[] args) throws ScriptException, IOException { ScriptEngineManager factory=new ScriptEngineManager(); ScriptEngine se=factory.getEngineByName("JavaScript"); ScriptContext sc=se.getContext(); sc.setAttribute("name", "kevin", ScriptContext.GLOBAL_SCOPE); se.eval("println(name)"); } }
kevin