Java中嵌入JavaScript脚本的思路:
1.取得脚本解释器的管理器Manager
2.从管理器中取得js的解释器实例ScriptEngine
3.取得存储javascript变量的Bindings实例
4.把一个java.io.Reader流及Bindings传递给ScriptEngine的eval()方法,从而运行存储在外部文件中的脚本。eval()方法返回脚本运行结果,如果执行中发生错误,会抛出ScriptException异常。
例:运行javascript脚本的一个java程序
- import java.io.*;
- import javax.script.Bindings;
- import javax.script.ScriptEngine;
- import javax.script.ScriptEngineManager;
- import javax.script.ScriptException;
-
- public class RunScript {
- public static void main(String[] args) throws IOException{
- ScriptEngineManager scriptManager = new ScriptEngineManager();
- ScriptEngine js = scriptManager.getEngineByExtension("js");
-
- String filename = null;
-
- Bindings bindings = js.createBindings();
-
- for(int i = 0;i<args.length;i++){
- String arg = args[i];
- if(arg.startsWith("-D")){
- int pos = arg.indexOf('=');
- if(pos == -1) usage();
- String name=arg.substring(2,pos);
- String value= arg.substring(pos+1);
-
- bindings.put(name, value);
- }else{
- if(filename!=null)usage();
- filename=arg;
- }
- }
-
- if(filename==null){
- usage();
- }
-
- bindings.put(ScriptEngine.FILENAME, filename);
-
- Reader in = new FileReader(filename);
- try{
-
- Object result = js.eval(in,bindings);
- System.out.println(result);
- }catch(ScriptException ex){
-
- System.out.println(ex);
- }
- }
- static void usage(){
- System.err.println("Usage: java RunScript[-Dname=value...] script.js");
- System.exit(1);
- }
- }
这段代码中所创建的Bindings对象不是静态的,JavaScript脚本所创建的所有的变量都存储在这里。下面是一个脚本化Java的更加实用的例子。它将它的Bindings对象存储在一个具有较高的作用域的ScriptContext对象中,以便可以读取其变量,但是新的变量就不存储到Binhdings对象中。这个例子实现了一个简单的配置文件工具,即一个文本文件,用来定义名字/值对,可以通过这里定义的Configuration类来查询它们。值可能是字符串、数字或布尔值,并且,如果一个值包含在花括号中,那么它就会传递给一个JavaScript解释器去计算。java.util.Map对象保存了这些包装在一个SimpleBindings对象中的值,这样一来,JavaScript解释器也可以访问同一个文件中定义的其他变量的值。
例:一个解释JavaScript表达式的Java配置文件工具
- import javax.script.*;
- import java.util.*;
- import java.io.*;
-
- public class Configuration {
- Map<String,Object> defaults = new HashMap<String,Object>();
-
- public Object get(String key){
- return defaults.get(key);
- }
- public void put(String key,Object value){
- defaults.put(key, value);
- }
-
- public void load(String filename) throws IOException,ScriptException{
-
- ScriptEngineManager manager = new ScriptEngineManager();
- ScriptEngine engine = manager.getEngineByExtension("js");
-
-
- Bindings bindings = new SimpleBindings(defaults);
-
- ScriptContext context = new SimpleScriptContext();
-
- context.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);
- BufferedReader in = new BufferedReader(new FileReader(filename));
- String line;
- while((line=in.readLine())!=null){
- line = line.trim();
- if(line.length()==0) continue;
- if(line.charAt(0)=='#')continue;
- int pos = line.indexOf(":");
- if(pos == -1){
- throw new IllegalArgumentException("syntax:"+line);
- }
- String name = line.substring(0,pos).trim();
- String value= line.substring(pos+1).trim();
- char firstchar = value.charAt(0);
- int len = value.length();
- char lastchar = value.charAt(len-1);
- if(firstchar=='"'&&lastchar=='"'){
-
- defaults.put(name, value.substring(1,len-1));
- }else if(Character.isDigit(firstchar)){
-
- try{
- double d = Double.parseDouble(value);
- defaults.put(name, value);
- }catch (NumberFormatException e) {
-
- defaults.put(name, value);
- }
- }else if("true".equals(value)){
- defaults.put(name,Boolean.TRUE);
- }else if("false".equals(value)){
- defaults.put(name, Boolean.FALSE);
- }else if("null".equals(value)){
- defaults.put(name, null);
- }else if(firstchar=='{'&&lastchar=='}'){
-
- String script = value.substring(1,len-1);
- Object result = engine.eval(script,context);
- defaults.put(name, result);
- }else{
-
- defaults.put(name, value);
- }
- }
- }
-
- public static void main(String[] args) throws IOException,ScriptException{
- Configuration defaults = new Configuration();
- defaults.load(args[0]);
- Set<Map.Entry<String, Object>> entryset = defaults.defaults.entrySet();
- for(Map.Entry<String, Object> entry:entryset){
- System.out.printf("%s:%s%n",entry.getKey(),entry.getValue());
- }
- }
- }