java和JavaScript有关系吗?长的挺像,开头好像一致,刚刚才看到一篇文章,有人在咖啡杯子下面写一个JavaScript,并宣称未来五年JavaScript将成为业界最重要的语言之一。嚓,一看这就是外行小编搞出来的文章,放出来也不知道给谁看的。又想到去年有个自命为程序员的女研究生(已毕业)来问我,“听说你是做java的?”“是啊,怎么?”“我这里有段代码有问题,你给我看看吧!”“好啊!”,谁知道,一看到代码我就晕菜了,那压根就是JavaScript代码,而且看的不是源码,而是浏览器执行后的源码,到处是硬编码,整个文件8000多行,用记事本打开的,我直接放弃了,说我也不会,然后被人家鄙视了一顿,哎,秀才遇上兵就是这意思吧!
虽然java是服务端代码,js是客户端代码,但java和Js并非没有联系,使用DWR方式进行前后端通信还是可以做到的,在js中可以直接使用java的方法,这个方案前些年一直被热炒,但这两年基本销声匿迹,或许存在一系列各种问题吧。
本文要说的是在Java中运行各种脚本代码比如JavaScript,Python,groovy等等,java支持所有JSR223标准的脚本代码,而支持js自然不在话下。
java调用脚本的优势是什么,为什么要调用脚本?
java是编译执行的语言,脚本可以直接解释执行,无需编译。一个场景,系统在生产环境中需要变更某些方法的实现方式但服务不能停止。为了能够直接修改而不用再重新编译且重启服务器,把脚本语言在Java中执行,通过修改脚本的实现来变更功能,就能解决问题。
以下是使用java调用脚本代码的示例:
public class ScriptEngineTest {
private final static String SCRIPT_PATH = "model.js";
private final static String FUNCTION_NAME = "formula";
private final static String FACTOR_NAME = "factor";
private final static String ENGINE_NAME = "javascript";
public static void runScript() throws ScriptException, NoSuchMethodException {
int var1 = 3;
int var2 = 2;
//1.创建脚本引擎
ScriptEngine engine = createScriptEngine();
//2.绑定全局变量
bindingContextVariable(engine);
//3.读取脚本内容
readScriptIntoEngine(engine);
//4.调用脚本方法,返回结果
Object result = invokeTargetMethod(engine, var1, var2);
System.out.println(result);
}
/**
* @param engine
* @param var1
* @param var2
* @throws ScriptException
* @throws NoSuchMethodException
*/
private static Object invokeTargetMethod(ScriptEngine engine, Object... args) throws NoSuchMethodException,
ScriptException {
Object result = null;
if (engine instanceof Invocable) {
Invocable io = (Invocable) engine;
result = io.invokeFunction(FUNCTION_NAME, args);
}
return result;
}
private static void readScriptIntoEngine(ScriptEngine engine) throws ScriptException {
InputStream resourceAsStream = ScriptEngineTest.class.getClassLoader().getResourceAsStream(SCRIPT_PATH);
Reader reader = new InputStreamReader(resourceAsStream);
engine.eval(reader);
}
private static void bindingContextVariable(ScriptEngine engine) {
Bindings binding = engine.createBindings();
binding.put(FACTOR_NAME, 5);
engine.setBindings(binding, ScriptContext.ENGINE_SCOPE);
}
private static ScriptEngine createScriptEngine() {
ScriptEngine engine = new ScriptEngineManager().getEngineByName(ENGINE_NAME);
return engine;
}
model.js
function formula(var1,var2){
return (var1+var2)/factor;
}