随着java的出现向java嵌入javascript脚本变的特别容易java引入了一个新的javaxscript包为脚本化语言提供了一个通用接口
案例; 小说网java中嵌入javascript脚本的思路
取得脚本解释器的管理器Manager
从管理器中取得js的解释器实例ScriptEngine
取得存储javascript变量的Bindings实例
把一个javaioReader流及Bindings传递给ScriptEngine的eval()方法从而运行存储在外部文件中的脚本eval()方法返回脚本运行结果如果执行中发生错误会抛出ScriptException异常
例运行javascript脚本的一个java程序
importjavaio*;
importjavaxscriptBindings;
importjavaxscriptScriptEngine;
importjavaxscriptScriptEngineManager;
importjavaxscriptScriptException;
/**
authorby?id=
*/
publicclassRunScript{
publicstaticvoidmain(String[]args)throwsIOException{
ScriptEngineManagerscriptManager=newScriptEngineManager();//得到解释器的管理器里面有很多种脚本解释器
ScriptEnginejs=scriptManagergetEngineByExtension(;js);//从管理器中获取js的解释器
//定义我们要运行的脚本文件
Stringfilename=null;
//通过解释器来获得存储javascript变量的Bindings的实例使它们提供给脚本
Bindingsbindings=jscreateBindings();
//处理参数参数是定义的脚本的变量参数可能包括Dname/value对我们要进行处理任何参数不能以D为文件名开始
for(inti=;i<argslength;i++){
Stringarg=args[i];
if(argstartsWith(D)){//如果参数是以D开头则进行处理
intpos=argindexOf(=);
if(pos==)usage();
Stringname=argsubstring(pos);
Stringvalue=argsubstring(pos+);
//注意我们定义的所有的变量是字符串如果必要的话我们可以通过javalangNumber一个javalangBoolean任何Java对象或NULL将脚本转换为其他类型
bindingsput(namevalue);//脚本中的变量存入bindings实例中
}else{
if(filename!=null)usage();
filename=arg;
}
}
//这里是为了确保我们得到了一个文件的参数
if(filename==null){
usage();
}
//增加一个具有约束力的使用特殊的保留变量名称告诉脚本引擎的文件的名称将执行这使它能够提供更好的错误信息
bindingsput(ScriptEngineFILENAMEfilename);
//读取文件的流
Readerin=newFileReader(filename);
try{
//执行脚本并取得结果注意in就相当于js中的脚本而bindings是脚本执行所需要的变量
Objectresult=jseval(inbindings);
Systemoutprintln(result);
}catch(ScriptExceptionex){
//执行过程中出异常则显示一个错误信息
Systemoutprintln(ex);
}
}
staticvoidusage(){
Systemerrprintln(Usage:javaRunScript[Dname=value]scriptjs);
Systemexit();//异常退出程序如果正常退出程序用Systemexit();
}
}
这段代码中所创建的Bindings对象不是静态的JavaScript脚本所创建的所有的变量都存储在这里下面是一个脚本化Java的更加实用的例子它将它的Bindings对象存储在一个具有较高的作用域的ScriptContext对象中以便可以读取其变量但是新的变量就不存储到Binhdings对象中这个例子实现了一个简单的配置文件工具即一个文本文件用来定义名字/值对可以通过这里定义的Configuration类来查询它们值可能是字符串数字或布尔值并且如果一个值包含在花括号中那么它就会传递给一个JavaScript解释器去计算javautilMap对象保存了这些包装在一个SimpleBindings对象中的值这样一来JavaScript解释器也可以访问同一个文件中定义的其他变量的值
importjavaxscript*;
importjavautil*;
importjavaio*;
/**
authorby;
*/
//这个类像javautilProperties但是允许属性值执行javascript表达式
publicclassConfiguration{
Map<StringObject>defaults=newHashMap<StringObject>();
//在map中获取和设置值的方法
publicObjectget(Stringkey){
returndefaultsget(key);
}
publicvoidput(StringkeyObjectvalue){
defaultsput(keyvalue);
}
//从map的name/value对中获取初始化内容如果一个值在大括号内表示是一个javascript脚本计算它
publicvoidload(Stringfilename)throwsIOExceptionScriptException{
//获得javascript编译器
ScriptEngineManagermanager=newScriptEngineManager();
ScriptEngineengine=managergetEngineByExtension(;js);
//使用我们的name/value对(即javascript变量)
Bindingsbindings=newSimpleBindings(defaults);
//创建一个变量用于存放脚本执行的内容
ScriptContextcontext=newSimpleScriptContext();
//设置那些Bindings在Context中使它们可读但这样的变量定义的脚本不要放入我们的Map中
contextsetBindings(bindingsScriptContextGLOBAL_SCOPE);
BufferedReaderin=newBufferedReader(newFileReader(filename));
Stringline;
while((line=inreadLine())!=null){
line=linetrim();
if(linelength()==)continue;//跳过空行
if(linecharAt()==#)continue;//跳过命令
intpos=lineindexOf(:);
if(pos==){
thrownewIllegalArgumentException(syntax:+line);
}
Stringname=linesubstring(pos)trim();
Stringvalue=linesubstring(pos+)trim();
charfirstchar=valuecharAt();
intlen=valuelength();
charlastchar=valuecharAt(len);
if(firstchar==&&lastchar==){
//双引号引用的值为字符串
defaultsput(namevaluesubstring(len));
}elseif(CharacterisDigit(firstchar)){
//如果开始是一个数字
try{
doubled=DoubleparseDouble(value);
defaultsput(namevalue);
}catch(NumberFormatExceptione){
//没有数字是一个string
defaultsput(namevalue);
}
}elseif(trueequals(value)){//处理布尔值
defaultsput(nameBooleanTRUE);
}elseif(falseequals(value)){
defaultsput(nameBooleanFALSE);
}elseif(nullequals(value)){//处理null值
defaultsput(namenull);
}elseif(firstchar=={&&lastchar==}){
//如果值是在一对大括号之内则执行javascript代码
Stringscript=valuesubstring(len);
Objectresult=engineeval(scriptcontext);
defaultsput(nameresult);
}else{
//其它情况刚好是一个字符串
defaultsput(namevalue);
}
}
}
//一个简单的类的测试程序
publicstaticvoidmain(String[]args)throwsIOExceptionScriptException{
Configurationdefaults=newConfiguration();
defaultsload(args[]);
Set<MapEntry<StringObject>>entryset=defaultsdefaultsentrySet();
for(MapEntry<StringObject>entry:entryset){
Systemoutprintf(%s:%s%nentrygetKey()entrygetValue());
}
}
}