java中嵌入javascript

来源:互联网 发布:数据库知识点总结 编辑:程序博客网 时间:2024/06/06 05:27
 http://blog.csdn.net/kqygww/article/details/8652386

Java中嵌入JavaScript脚本的思路: 
1.取得脚本解释器的管理器Manager 
2.从管理器中取得js的解释器实例ScriptEngine 
3.取得存储javascript变量的Bindings实例 
4.把一个java.io.Reader流及Bindings传递给ScriptEngine的eval()方法,从而运行存储在外部文件中的脚本。eval()方法返回脚本运行结果,如果执行中发生错误,会抛出ScriptException异常。 
例:运行javascript脚本的一个java程序

[java] view plain copy
  1. import java.io.*;  
  2. import javax.script.Bindings;  
  3. import javax.script.ScriptEngine;  
  4. import javax.script.ScriptEngineManager;  
  5. import javax.script.ScriptException;  
  6.   
  7. public class RunScript {  
  8.     public static void main(String[] args) throws IOException{  
  9.         ScriptEngineManager scriptManager = new ScriptEngineManager();//得到解释器的管理器,里面有很多种脚本解释器  
  10.         ScriptEngine js = scriptManager.getEngineByExtension("js");//从管理器中获取js的解释器  
  11.         //定义我们要运行的脚本文件  
  12.         String filename = null;  
  13.         //通过解释器来获得存储javascript变量的Bindings的实例,使它们提供给脚本。  
  14.         Bindings bindings = js.createBindings();  
  15.         //处理参数,参数是定义的脚本的变量。参数可能包括-Dname/value对。我们要进行处理,任何参数不能以‘-D’为文件名开始  
  16.         for(int i = 0;i<args.length;i++){  
  17.             String arg = args[i];  
  18.             if(arg.startsWith("-D")){//如果参数是以“-D”开头,则进行处理  
  19.                 int pos = arg.indexOf('=');  
  20.                 if(pos == -1) usage();  
  21.                 String name=arg.substring(2,pos);  
  22.                 String value= arg.substring(pos+1);  
  23.                 //注意:我们定义的所有的变量是字符串,如果必要的话,我们可以通过java.lang.Number ,一个java.lang.Boolean,任何Java对象或NULL,将脚本转换为其他类型。  
  24.                 bindings.put(name, value);//脚本中的变量存入bindings实例中  
  25.             }else{  
  26.                 if(filename!=null)usage();  
  27.                 filename=arg;  
  28.             }  
  29.         }  
  30.         //这里是为了确保我们得到了一个文件的参数。  
  31.         if(filename==null){  
  32.             usage();  
  33.         }  
  34.         //增加一个具有约束力的使用特殊的保留变量名称,告诉脚本引擎的文件的名称将执行。这使它能够提供更好的错误信息  
  35.         bindings.put(ScriptEngine.FILENAME, filename);  
  36.         //读取文件的流  
  37.         Reader in = new FileReader(filename);  
  38.         try{  
  39.             //执行脚本并取得结果。注意in就相当于js中的脚本,而bindings是脚本执行所需要的变量  
  40.             Object result = js.eval(in,bindings);  
  41.             System.out.println(result);  
  42.         }catch(ScriptException ex){  
  43.             //执行过程中出异常则显示一个错误信息  
  44.             System.out.println(ex);  
  45.         }  
  46.     }  
  47.     static void usage(){  
  48.         System.err.println("Usage: java RunScript[-Dname=value...] script.js");  
  49.         System.exit(1);//异常退出程序。如果正常退出程序用System.exit(0);  
  50.     }  
  51. }  

这段代码中所创建的Bindings对象不是静态的,JavaScript脚本所创建的所有的变量都存储在这里。下面是一个脚本化Java的更加实用的例子。它将它的Bindings对象存储在一个具有较高的作用域的ScriptContext对象中,以便可以读取其变量,但是新的变量就不存储到Binhdings对象中。这个例子实现了一个简单的配置文件工具,即一个文本文件,用来定义名字/值对,可以通过这里定义的Configuration类来查询它们。值可能是字符串、数字或布尔值,并且,如果一个值包含在花括号中,那么它就会传递给一个JavaScript解释器去计算。java.util.Map对象保存了这些包装在一个SimpleBindings对象中的值,这样一来,JavaScript解释器也可以访问同一个文件中定义的其他变量的值。

例:一个解释JavaScript表达式的Java配置文件工具

[java] view plain copy
  1. import javax.script.*;  
  2. import java.util.*;  
  3. import java.io.*;  
  4. //这个类像java.util.Properties ,但是允许属性值执行javascript表达式  
  5. public class Configuration {  
  6.     Map<String,Object> defaults = new HashMap<String,Object>();  
  7.     //在map中获取和设置值的方法  
  8.     public Object get(String key){  
  9.         return defaults.get(key);  
  10.     }  
  11.     public void put(String key,Object value){  
  12.         defaults.put(key, value);  
  13.     }  
  14.     //从map的name/value对中获取初始化内容。如果一个值在大括号内,表示是一个javascript脚本,计算它  
  15.     public void load(String filename) throws IOException,ScriptException{  
  16.         //获得javascript编译器  
  17.         ScriptEngineManager manager = new ScriptEngineManager();  
  18.         ScriptEngine engine = manager.getEngineByExtension("js");  
  19.           
  20.         //使用我们的name/value对(即javascript变量)  
  21.         Bindings bindings = new SimpleBindings(defaults);  
  22.         //创建一个变量,用于存放脚本执行的内容  
  23.         ScriptContext context  = new SimpleScriptContext();  
  24.         //设置那些Bindings 在Context 中,使它们可读。但这样的变量定义的脚本不要放入我们的Map中  
  25.         context.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);  
  26.         BufferedReader in  = new BufferedReader(new FileReader(filename));  
  27.         String line;  
  28.         while((line=in.readLine())!=null){  
  29.             line = line.trim();  
  30.             if(line.length()==0continue;//跳过空行  
  31.             if(line.charAt(0)=='#')continue;//跳过命令  
  32.             int pos = line.indexOf(":");  
  33.             if(pos == -1){  
  34.                 throw new IllegalArgumentException("syntax:"+line);  
  35.             }  
  36.             String name = line.substring(0,pos).trim();  
  37.             String value= line.substring(pos+1).trim();  
  38.             char firstchar = value.charAt(0);  
  39.             int len = value.length();  
  40.             char lastchar = value.charAt(len-1);  
  41.             if(firstchar=='"'&&lastchar=='"'){  
  42.                 //双引号引用的值为字符串  
  43.                 defaults.put(name, value.substring(1,len-1));  
  44.             }else if(Character.isDigit(firstchar)){  
  45.                 //如果开始是一个数字  
  46.                 try{  
  47.                     double d = Double.parseDouble(value);  
  48.                     defaults.put(name, value);  
  49.                 }catch (NumberFormatException e) {  
  50.                     //没有数字,是一个string  
  51.                     defaults.put(name, value);  
  52.                 }  
  53.             }else if("true".equals(value)){//处理布尔值  
  54.                 defaults.put(name,Boolean.TRUE);  
  55.             }else if("false".equals(value)){  
  56.                 defaults.put(name, Boolean.FALSE);  
  57.             }else if("null".equals(value)){//处理null值  
  58.                 defaults.put(name, null);  
  59.             }else if(firstchar=='{'&&lastchar=='}'){  
  60.                 //如果值是在一对大括号之内,则执行javascript代码  
  61.                 String script = value.substring(1,len-1);  
  62.                 Object result = engine.eval(script,context);  
  63.                 defaults.put(name, result);  
  64.             }else{  
  65.                 //其它情况,刚好是一个字符串  
  66.                 defaults.put(name, value);  
  67.             }  
  68.         }  
  69.     }  
  70.     //一个简单的类的测试程序  
  71.     public static void main(String[] args) throws IOException,ScriptException{  
  72.         Configuration defaults = new Configuration();  
  73.         defaults.load(args[0]);  
  74.         Set<Map.Entry<String, Object>> entryset = defaults.defaults.entrySet();  
  75.         for(Map.Entry<String, Object> entry:entryset){  
  76.             System.out.printf("%s:%s%n",entry.getKey(),entry.getValue());  
  77.         }  
  78.     }  
  79. }  
原创粉丝点击