使用java运行javaScript脚本

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



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值