阅读(817) (0)

Java 脚本上下文

2017-01-09 19:33:42 更新

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);
  }
}