Java脚本教程 – Java脚本上下文
脚本引擎在上下文或环境中执行脚本。
ScriptContext
接口的实例表示脚本的上下文。
SimpleScriptContext
类是 ScriptContext
接口的实现。
脚本上下文由四个组件组成:
- 与不同范围相关联的绑定。上下文中的绑定将参数传递给脚本。
- 读取器读取输入
- 写入输出
- 写入错误输出的错误写入器
例子
以下代码使用SimpleScriptContext类创建ScriptContext。
SimpleScriptContext类的一个实例维护Bindings的两个实例:一个用于引擎范围,一个用于全局范围。
默认情况下,SimpleScriptContext类分别将上下文的输入阅读器,输出写入程序和错误写入程序初始化为 System.in
, System.out
和 System.err
。
ScriptContext接口的getReader(),getWriter()和getErrorWriter()方法分别返回来自ScriptContext的读者,写者和错误写入者的引用。
Setter方法可以设置读写器。
以下代码显示如何获取读写器。它还显示如何设置写入器到FileWriter以将脚本输出写入文件:
import java.io.FileWriter; import java.io.Reader; import java.io.Writer; import javax.script.ScriptContext; import javax.script.SimpleScriptContext; public class Main { public static void main(String[] args) throws Exception{ ScriptContext ctx = new SimpleScriptContext(); // Get the reader and writers from the script context Reader inputReader = ctx.getReader(); Writer outputWriter = ctx.getWriter(); Writer errWriter = ctx.getErrorWriter(); // Write all script outputs to an out.txt file Writer fileWriter = new FileWriter("out.txt"); ctx.setWriter(fileWriter); } }
添加上下文
创建 SimpleScriptContext
后,您可以开始在引擎范围绑定中存储键值对。
setAttribute()
方法用于向Bindings添加键值对。
以下代码显示如何添加三个键值对。
import javax.script.ScriptContext; import javax.script.SimpleScriptContext; public class Main { public static void main(String[] args) throws Exception{ ScriptContext ctx = new SimpleScriptContext(); ctx.setAttribute("year", 2015, ScriptContext.ENGINE_SCOPE); ctx.setAttribute("month", 9, ScriptContext.ENGINE_SCOPE); ctx.setAttribute("day", 21, ScriptContext.ENGINE_SCOPE); } }
将绑定添加到GLOBAL_SCOPE
要将键值对添加到全局范围中的绑定,请首先创建和设置绑定。
import javax.script.Bindings; import javax.script.ScriptContext; import javax.script.SimpleBindings; import javax.script.SimpleScriptContext; public class Main { public static void main(String[] args) throws Exception { ScriptContext ctx = new SimpleScriptContext(); Bindings globalBindings = new SimpleBindings(); ctx.setBindings(globalBindings, ScriptContext.GLOBAL_SCOPE); ctx.setAttribute("year", 2015, ScriptContext.GLOBAL_SCOPE); ctx.setAttribute("name", "Java", ScriptContext.GLOBAL_SCOPE); } }
解决不同范围的变量
import static javax.script.ScriptContext.ENGINE_SCOPE; import static javax.script.ScriptContext.GLOBAL_SCOPE; import java.util.List; import javax.script.Bindings; import javax.script.ScriptContext; import javax.script.SimpleBindings; import javax.script.SimpleScriptContext; public class Main { public static void main(String[] args) { ScriptContext ctx = new SimpleScriptContext(); List<Integer> scopes = ctx.getScopes(); System.out.println("Supported Scopes: " + scopes); ctx.setAttribute("year", 2015, ENGINE_SCOPE); Bindings globalBindings = new SimpleBindings(); ctx.setBindings(globalBindings, GLOBAL_SCOPE); ctx.setAttribute("year", 2014, GLOBAL_SCOPE); ctx.setAttribute("name", "Jack", GLOBAL_SCOPE); String nameValue = (String) ctx.getAttribute("name"); System.out.println("nameValue = " + nameValue); int engineScopeYear = (Integer) ctx.getAttribute("year", ENGINE_SCOPE); int globalScopeYear = (Integer) ctx.getAttribute("year", GLOBAL_SCOPE); System.out.println("engineScopeYear = " + engineScopeYear); System.out.println("globalScopeYear = " + globalScopeYear); } }
上面的代码生成以下结果。
例3
使用由同一ScriptEngineManager创建的引擎的全局和引擎范围绑定。
import static javax.script.ScriptContext.ENGINE_SCOPE; import static javax.script.ScriptContext.GLOBAL_SCOPE; import javax.script.Bindings; import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import javax.script.SimpleScriptContext; public class Main { public static void main(String[] args) throws ScriptException { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("JavaScript"); manager.put("n1", 1); String script = "var sum = n1 + n2;print(msg + " + "" n1=" + n1 + ", n2=" + n2 + " + "", sum=" + sum);"; engine.put("n2", 2); engine.put("msg", "a string"); engine.eval(script); Bindings bindings = engine.createBindings(); bindings.put("n2", 3); bindings.put("msg", "another string"); engine.eval(script, bindings); ScriptContext ctx = new SimpleScriptContext(); Bindings ctxGlobalBindings = engine.createBindings(); ctx.setBindings(ctxGlobalBindings, GLOBAL_SCOPE); ctx.setAttribute("n1", 4, GLOBAL_SCOPE); ctx.setAttribute("n2", 5, ENGINE_SCOPE); ctx.setAttribute("msg", "ScriptContext:", ENGINE_SCOPE); engine.eval(script, ctx); engine.eval(script); } }
上面的代码生成以下结果。
更改默认ScriptContext
分别使用getContext()和setContext()方法获取和设置ScriptEngine的默认上下文,如下所示:
import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import javax.script.SimpleScriptContext; public class Main { public static void main(String[] args) throws ScriptException { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("JavaScript"); ScriptContext defaultCtx = engine.getContext(); // Work with defaultCtx here // Create a new context ScriptContext ctx = new SimpleScriptContext(); // Configure ctx here engine.setContext(ctx); } }
要在新的默认上下文中使用ScriptEngineManager的绑定,请如下所示明确设置:
import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import javax.script.SimpleScriptContext; public class Main { public static void main(String[] args) throws ScriptException { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("JavaScript"); ScriptContext defaultCtx = engine.getContext(); // Work with defaultCtx here // Create a new context ScriptContext ctx = new SimpleScriptContext(); // Configure ctx here // Set ctx as the new default context for the engine engine.setContext(ctx); ctx.setBindings(manager.getBindings(), ScriptContext.GLOBAL_SCOPE); engine.setContext(ctx); } }