您的位置:首页 > Web前端 > JavaScript

java中嵌入javascript

zdy0_2004 2017-07-07 17:46 20 查看
 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

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");//从管理器中获取js的解释器  

        //定义我们要运行的脚本文件  

        String filename = null;  

        //通过解释器来获得存储javascript变量的Bindings的实例,使它们提供给脚本。  

        Bindings bindings = js.createBindings();  

        //处理参数,参数是定义的脚本的变量。参数可能包括-Dname/value对。我们要进行处理,任何参数不能以‘-D’为文件名开始  

        for(int i = 0;i<args.length;i++){  

            String arg = args[i];  

            if(arg.startsWith("-D")){//如果参数是以“-D”开头,则进行处理  

                int pos = arg.indexOf('=');  

                if(pos == -1) usage();  

                String name=arg.substring(2,pos);  

                String value= arg.substring(pos+1);  

                //注意:我们定义的所有的变量是字符串,如果必要的话,我们可以通过java.lang.Number ,一个java.lang.Boolean,任何Java对象或NULL,将脚本转换为其他类型。  

                bindings.put(name, value);//脚本中的变量存入bindings实例中  

            }else{  

                if(filename!=null)usage();  

                filename=arg;  

            }  

        }  

        //这里是为了确保我们得到了一个文件的参数。  

        if(filename==null){  

            usage();  

        }  

        //增加一个具有约束力的使用特殊的保留变量名称,告诉脚本引擎的文件的名称将执行。这使它能够提供更好的错误信息  

        bindings.put(ScriptEngine.FILENAME, filename);  

        //读取文件的流  

        Reader in = new FileReader(filename);  

        try{  

            //执行脚本并取得结果。注意in就相当于js中的脚本,而bindings是脚本执行所需要的变量  

            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);//异常退出程序。如果正常退出程序用System.exit(0);  

    }  

}  

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

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

[java] view
plain copy

import javax.script.*;  

import java.util.*;  

import java.io.*;  

//这个类像java.util.Properties ,但是允许属性值执行javascript表达式  

public class Configuration {  

    Map<String,Object> defaults = new HashMap<String,Object>();  

    //在map中获取和设置值的方法  

    public Object get(String key){  

        return defaults.get(key);  

    }  

    public void put(String key,Object value){  

        defaults.put(key, value);  

    }  

    //从map的name/value对中获取初始化内容。如果一个值在大括号内,表示是一个javascript脚本,计算它  

    public void load(String filename) throws IOException,ScriptException{  

        //获得javascript编译器  

        ScriptEngineManager manager = new ScriptEngineManager();  

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

          

        //使用我们的name/value对(即javascript变量)  

        Bindings bindings = new SimpleBindings(defaults);  

        //创建一个变量,用于存放脚本执行的内容  

        ScriptContext context  = new SimpleScriptContext();  

        //设置那些Bindings 在Context 中,使它们可读。但这样的变量定义的脚本不要放入我们的Map中  

        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) {  

                    //没有数字,是一个string  

                    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)){//处理null值  

                defaults.put(name, null);  

            }else if(firstchar=='{'&&lastchar=='}'){  

                //如果值是在一对大括号之内,则执行javascript代码  

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

        }  

    }  

}  
标签:  java JavaScript