Java6 Script Engine使用

来源:互联网 发布:轨迹软件 编辑:程序博客网 时间:2024/05/16 13:51

在默认情况下,Java SE6只支持javascript,但这也提供了一些接口,也就是脚本规范,JSR223。通过这些接口,Java SE6可以支持任意的脚本语言。


在javax.script包中有很多的类,但这些类中最主要的是ScripEngineManager。通过这个类得到当前Java SE6所支持的所有脚本。

import javax.script.*;  import java.io.*;  import java.util.*;  import static java.lang.System.*;  public class ListScriptEngines  {  public static void main(String args[]){  ScriptEngineManager manager = new ScriptEngineManager();  // 得到所有的脚本引擎工厂  List factories = manager.getEngineFactories();  // 这是Java SE 5 和Java SE 6的新For语句语法  for (ScriptEngineFactory factory: factories){  // 打印脚本信息  out.printf("Name: %s%n" +  "Version: %s%n" +  "Language name: %s%n" +  "Language version: %s%n" +  "Extensions: %s%n" +  "Mime types: %s%n" +  "Names: %s%n",  factory.getEngineName(),  factory.getEngineVersion(),  factory.getLanguageName(),  factory.getLanguageVersion(),  factory.getExtensions(),  factory.getMimeTypes(),  factory.getNames());  // 得到当前的脚本引擎  ScriptEngine engine = factory.getScriptEngine();  }   } }


其中import static java.lang.System.*是将System中的所有静态成员进行引用。得到一个具体的脚本引擎有3种方法。

(1)根据扩展名得到脚本引擎

ScriptEngine engine = manager.getEngineByExtension("js");

(2)根据Mime类型得到脚本引擎

ScriptEngine engine = manager.getEngineByMimeType("text/javascript");
(3)根据名称得到脚本引擎

ScriptEngine engine = manager.getEngineByName("javascript");


可以使用ScriptEngine的eval方法来执行脚本,eval方法被重载的多次,但最常用的是public Object eval(String script)。


import javax.script.*;  import java.io.*;  import static java.lang.System.*;  public class FirstJavaScript  {  public static void main(String args[])  {  ScriptEngineManager manager = new ScriptEngineManager();  // 得到javascript脚本引擎  ScriptEngine engine = manager.getEngineByName("javascript");  try  {  // 开始运行脚本,并返回当前的小时  Double hour = (Double)engine.eval("var date = new Date();" +"date.getHours();");  String msg;  // 将小时转换为问候信息  if (hour < 10)  {  msg = "上午好";  }  else if (hour < 16)  {  msg = "下午好";  }  else if (hour < 20)  {  msg = "晚上好";  }  else  {  msg = "晚安";  }  out.printf("小时%s: %s%n", hour, msg);  }  catch (ScriptException e)  {  err.println(e);  }  }  }


和脚本语言进行交互

ScriptEngine有两个方法put和get:

(1)put有两个参数,一个是脚本变量名,另一个是变量的值,这个值是Object类型,因此,可以传递任何值。

(2)get有一个参数,就是脚本变量的名。

import javax.script.*;  import java.io.*;  import static java.lang.System.*;  public class ReverseString  {  public static void main(String args[])  {  ScriptEngineManager manager = new ScriptEngineManager();  // 建立javascript脚本引擎  ScriptEngine engine = manager.getEngineByName("javascript");  try  {  // 将变量name和变量值abcdefg传给javascript脚本  engine.put("name", "abcdefg");  // 开始执行脚本  engine.eval("var output ='' ;" +  "for (i = 0; i <= name.length; i++) {" +  " output = name.charAt(i) + output" +  "}");  // 得到output变量的值  String name = (String)engine.get("output");  out.printf("被翻转后的字符串:%s", name);  }  catch (ScriptException e)  {  err.println(e);  }  }  }



compilable接口

只有实现了Compilable接口的脚本引擎才可以使用compile进行编译(这里的编译一般将不是生成可执行文件,而只是在内存中编译成更容易运行的方式),可以使用ScriptEngine的compile方法进行编译。

import javax.script.*;  import java.io.*;  import static java.lang.System.*;  public class CompileScript  {  public static void main(String args[])  {  ScriptEngineManager manager = new ScriptEngineManager();  ScriptEngine engine = manager.getEngineByName("javascript");  engine.put("counter", 0); // 向javascript传递一个参数  // 判断这个脚本引擎是否支持编译功能  if (engine instanceof Compilable)  {  Compilable compEngine = (Compilable)engine;  try  {  // 进行编译  CompiledScript script = compEngine.compile("function count() { " +  " counter = counter +1; " +  " return counter; " +  "}; count();");  out.printf("Counter: %s%n", script.eval());  out.printf("Counter: %s%n", script.eval());  out.printf("Counter: %s%n", script.eval());  }  catch (ScriptException e)  {  err.println(e);  }  }  else  {  err.println("这个脚本引擎不支持编译!");  }  }  }


Invocable接口

实现Invocable接口可以动态调用脚本语言中的方法。


import javax.script.*;  import java.io.*;  import static java.lang.System.*;  public class InvocableTest  {  public static void main(String args[])  {  ScriptEngineManager manager = new ScriptEngineManager();  ScriptEngine engine = manager.getEngineByName("javascript");  String name="abcdefg";  if (engine instanceof Invocable)  {  try  {  engine.eval("function reverse(name) {" +  " var output =' ';" +  " for (i = 0; i <= name.length; i++) {" +  " output = name.charAt(i) + output" +  " } return output;}");  Invocable invokeEngine = (Invocable)engine;  Object o = invokeEngine.invokeFunction("reverse", name);  out.printf("翻转后的字符串:%s", o);  }  catch (NoSuchMethodException e)  {  err.println(e);  }  catch (ScriptException e)  {  err.println(e);  }  }  else  {  err.println("这个脚本引擎不支持动态调用");  }  }

动态实现接口

如果我们要想让脚本异步地执行,即通过多线程来执行,那InvokeEngine类必须实现Runnable接口才可以通过Thread启动多线程。

  import javax.script.*;  import static java.lang.System.*;  public class InterfaceTest  {  public static void main(String args[])  {  ScriptEngineManager manager = new ScriptEngineManager();  ScriptEngine engine = manager.getEngineByName("javascript");  try  {  engine.eval("function run() {print(异步调用);}");  Invocable invokeEngine = (Invocable)engine;  Runnable runner = invokeEngine.getInterface(Runnable.class);  Thread t = new Thread(runner);  t.start();  t.join();  }  catch (InterruptedException e)  {  err.println(e);  }  catch (ScriptException e)  {  System.err.println(e);  }  }  }



0 0
原创粉丝点击