<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span><span style="background-color: rgb(255, 255, 255); font-family: 'Microsoft YaHei'; font-size: 14px;"> ScriptEngine,顾名思义就是一种脚本引擎,可以用Java语言来调用其他脚本语言,比如Javascript,python等。以前我们都是在Javascript代码里面来通过servlet或者action来调用Java代码,ScriptEngine很有意思,可以让我们在Java代码里调用js的方法。</span>
ScriptEngine 预定于全局变量 其实JDK ScriptEngine预定于全局变量和预定于Funciton是一样的,都需要GLOBAL_SCOPE类型的Bindings对象。 所以在调用我们预定写好的function时,先要设置好相关的全局变量。比如我们预先写好的一个js方法(在src/com/licq/scripts/model.js文件中):
function compute(var1,var2){
return var1*multiplier+var2-devider;
}
其中multiplier,devider是全局变量需要在调用function之前就要设置好的。var1,var2是我们函数的入参。
下面是java代码的开发调用,以前来探究ScriptEngine的神奇:
package com.licq.scripts;
import java.io.File;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import javax.script.Bindings;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class ScriptUtils {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
String filePath = new File("").getAbsolutePath()+"\\src\\com\\licq\\scripts\\model.js";
Map map = new HashMap();
map.put("multiplier", 5);//设置上下文全局变量
map.put("devider", 2);//设置上上下文全局变量
invokeJavaScript(filePath,"compute",map);//调用方法(var1,var2)
}
/**
* @param scriptFilePath String 脚本文件的路径
* @param functionName String 调用的脚本的函数名称
* @param parameters Map 调用函数时使用的上下文环境变量集合
*
*
* */
private static void invokeJavaScript(String scriptFilePath,String functionName,Map parameters) throws Exception{
//获得一个javascipt的执行引擎
ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
//建立上下文变量
Bindings bind = engine.createBindings();
Iterator it = (Iterator) parameters.entrySet().iterator();
while(it.hasNext()){
Map.Entry entry = (Entry) it.next();
bind.put(String.valueOf(entry.getKey()), entry.getValue());
}
//绑定上下文,作用域是当前引擎规范
engine.setBindings(bind, ScriptContext.ENGINE_SCOPE);
System.out.println("请输入2个整数:");
Scanner input = new Scanner(System.in);
while(input.hasNextInt()){
int first = input.nextInt();
int second = input.nextInt();
System.out.println("输入的参数是:"+first+","+second);
//执行js代码
engine.eval(new FileReader(scriptFilePath));
//是否可调用方法
if(engine instanceof Invocable){
Invocable in = (Invocable)engine;
//执行js中的函数
Double result= (Double)in.invokeFunction(functionName, first,second);
//打印出调用方法的结果:
System.out.println(functionName+"("+first+","+second+")的运算结果是:"+result.intValue());
}
}
}
}
我们启动main方法,然后在console中输入2个参数,最后打印出调用的结果如下:
请输入2个整数:
3
5
输入的参数是:3,5
compute(3,5)的运算结果是:18
var1*multiplier+var2-devider(
multiplier=5,devider=2)用数字换算:3*5+5-2=18.结果完全正确。
我个人认为ScriptEngine以后有很多地方可以使用,比如在某些流程中业务规则校验的时候,可以用脚本配置计算公式等来计算,比较灵活而且易调整。当然还有其他很多地方的用处,需要大家一起集思广益。