fun

 

js嵌入到java程序中

  随着java6.0的出现,向java嵌入javascript脚本变的特别容易。java6引入了一个新的javax.script包,为脚本化语言提供了一个通用接口。 
 案例:http://www.5a520.cn  小说520网
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;   
 
/**
author by 
http://www.bt285.cn/content.php?id=1196863 
*/

public class RunScript {   
    
public static void main(String[] args) throws IOException{   
        ScriptEngineManager scriptManager 
= new ScriptEngineManager();//得到解释器的管理器,里面有很多种脚本解释器   
        ScriptEngine js = scriptManager.getEngineByExtension("http://www.bt285.cn/aidesefang/ 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解释器也可以访问同一个文件中定义的其他变量的值。

import javax.script.*;   
import java.util.*;   
import java.io.*;   
/**
author by 
http://www.bt285.cn/sejishikong/ 
*/

//这个类像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("http://www.bt285.cn/yazhou/ 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()==0continue;//跳过空行   
            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());   
        }
   
    }
   
}
  

posted on 2009-05-04 19:30 fun 阅读(2430) 评论(0)  编辑  收藏

导航

统计

常用链接

留言簿(11)

随笔档案

友情链接

搜索

最新评论

阅读排行榜

评论排行榜