使用java运行javaScript脚本

来源:互联网 发布:seo推广 编辑:程序博客网 时间:2024/06/05 23:45

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;}


只要修改formula方法的实现方式就能变更功能,这样做显得很简单吧!关于执行的步骤请参考代码注释四步。这四个步骤中第二步是可以省略的,如果没有上下文变量(可以认为是脚本中用到的全局变量),可以不绑定。其他三步都是必须的。



0 0
原创粉丝点击