100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Java中运行js代码

Java中运行js代码

时间:2022-05-01 06:36:48

相关推荐

Java中运行js代码

项目需求:

客户动态填写一些规则,根据规则生成告警提醒变化之类的信息,例如温度过高给出告警,设备属性变化给出提示等等。然而客户的判断这些变化的规则是不断改变的,因此需要动态输入。jvm支持多种动态语言,我们可以从java中调用JavaScript、Groovy、Ruby以及Scheme和Haskell编写的脚本,考虑到语言的流行程度,我们选择了js。

实例代码:

本代码主要来自《写给大忙人看的Jave SE 9核心技术》一书第14章,编译与脚本。

首先,我们需要获取脚本执行引擎。脚本执行引擎就是以特定语言执行脚本的类库。jvm启动是,就会启动这些脚本引擎,我们可以通过new ScriptEngineManager()来获取脚本引擎管理器,然后通过getEngineByName(…)方法获取的对应的脚本引擎,我们使用的JavaScript语言,因此使用参数“nashorn”获取ScriptEngine。

注意:There is no requirement for a given Java Virtual Machine (JVM) to include any engines by default, but the Oracle JVM (Java 6 and later) includes a JavaScript engine, based on Rhino version 1.6R2 before Java 8, and Nashorn since Java 8.

Java 8 之前的jvm中JavaScript的ScriptEngine name Rhino, 之后的是nashorn

官方文档:

/aboutJava/communityprocess/final/jsr223/index.html Scripting for the JavaTM Platform

package com.yq.js;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import lombok.experimental.var;import lombok.extern.slf4j.Slf4j;import lombok.extern.java.Log;import javax.script.Bindings;import javax.script.Invocable;import javax.script.ScriptEngine;import javax.script.ScriptEngineManager;import javax.script.ScriptException;import java.io.File;import java.io.Reader;import java.io.StringWriter;import java.nio.charset.Charset;import java.nio.file.Files;import java.nio.file.Path;/*** Simple to Introduction* className: JavaJSDemo** @author EricYang* @version /12/22 9:51*/@Slf4jpublic class JavaJSDemo {private static final String JS_ENGINE_NAME= "JavaScript";private final ScriptEngineManager sem = new ScriptEngineManager();private final ScriptEngine engine = sem.getEngineByName(JS_ENGINE_NAME);public static void main(String[] args) {JavaJSDemo demo = new JavaJSDemo();demo.bindingDemo();demo.reDirectIODemo();demo.invokeFunctionDemo();demo.invokeFunctionByFileDemo();}public void bindingDemo() {try {engine.put("msg", "hello world!");Object result = engine.eval("msg");log.info("result=" + result);engine.put("k", 20);result = engine.eval("k + 1");log.info("result=" + result);result = engine.eval("n = 1738");log.info("result=" + result);result = engine.get("n");log.info("result=" + result);Bindings scope = engine.createBindings();scope.put("key", "西安");result = engine.eval("key + '市'", scope);log.info("result=" + result);}catch (ScriptException se) {log.warn("binding demo exception.", se);}}public void reDirectIODemo() {log.info("---redirect IO---" );try {StringWriter writer = new StringWriter();engine.getContext().setWriter(writer);engine.put("msg", "hello world!");//任何一print函数输出的内容都会送到writer对象中Object result = engine.eval("print(msg)");log.info("result=" + result);log.info("result=" + writer.toString());//js中直接调用java的System.out.printlnresult = engine.eval("java.lang.System.out.println(msg)");log.info("result=" + result);log.info("result=" + writer.toString());}catch (ScriptException se) {log.warn("binding demo exception.", se);}}public boolean invokeFunctionDemo() {log.info("---invokeFunction ---" );boolean result = true;try {engine.put("msg", "hello world!");String str = "var user = {name:'张三',age:18,city:['陕西','台湾']};";engine.eval(str);log.info("Get msg={}", engine.get("msg"));//获取变量engine.eval("var sum = eval('1 + 2 + 3*4');");//调用js的eval的方法完成运算log.info("get sum={}", engine.get("sum"));JSONObject msg = new JSONObject();msg.put("temperature", 125);msg.put("humidity", 20);msg.put("voltage", 220);msg.put("electricity", 13);JSONObject metadata = new JSONObject();metadata.put("deviceName", "空气质量检测器01");metadata.put("contacts", "张三");JSONObject msgType = new JSONObject();//msgType.put("type", "deviceTelemetryData");msgType.put("type", "deviceTelemetryData1");//定义函数String func = "var result = true; \r\n" +"if (msgType.type = 'deviceTelemetryData') { \r\n" +" if (msg.temperature >0 && msg.temperature < 33) { \n result = true ;} \n" +" else { \n result = false;} \n" +"} else { \nresult = false; \n" +"var errorMsg = msgType.type + ' is not deviceTelemetryData'; \n" +"print(msgType.type) \n } \n\n" +"return result";log.info("func = {}", func);engine.eval("function filter(msg, metadata, msgType){ " + func + "}");// 执行js函数Invocable jsInvoke = (Invocable) engine;Object obj = jsInvoke.invokeFunction("filter", msg, metadata, msgType);//方法的名字,参数log.info("function result={}", obj);result = (Boolean)obj;}catch(Exception ex) {log.warn("exception", ex);result = false;}return result;}public int invokeFunctionByFileDemo() {log.info("---invokeFunction ---" );int result = 0;try {log.info("Current dir={}", System.getProperty("user.dir"));//\AkkaDemo\src\main\resources\demo.jsFile file = new File("./AkkaDemo/src/main/resources/demo.js");Reader reader = Files.newBufferedReader(file.toPath(), Charset.defaultCharset());engine.put("user", "{name:'张三',age:18,city:['陕西','台湾']};");Object obj = engine.eval(reader);log.info("get age={}", engine.get("age"));log.info("function result={}", obj);URL resource = this.getClass().getClassLoader().getResource("demo2.js");FileReader fileReader = new FileReader(resource.getPath());engine.eval(fileReader);//执行js函数Invocable jsInvoke = (Invocable)engine;obj = jsInvoke.invokeFunction("myAdd", 1, 2);log.info("myAdd obj={}", obj);}catch(Exception ex) {log.warn("exception", ex);}return result;}}

说明:

1,demo.js 内容为 var age = 20;

2,demo2.js 内容为

function myAdd(a,b){

var sum = a + b;

return sum;

}

运行效果:

11:34:26.170 [main] INFO com.yq.js.JavaJSDemo - result=hello world!11:34:26.186 [main] INFO com.yq.js.JavaJSDemo - result=21.011:34:26.195 [main] INFO com.yq.js.JavaJSDemo - result=173811:34:26.195 [main] INFO com.yq.js.JavaJSDemo - result=173811:34:26.205 [main] INFO com.yq.js.JavaJSDemo - result=西安市11:34:26.205 [main] INFO com.yq.js.JavaJSDemo - ---redirect IO---11:34:26.212 [main] INFO com.yq.js.JavaJSDemo - result=null11:34:26.213 [main] INFO com.yq.js.JavaJSDemo - result=hello world!hello world!11:34:26.253 [main] INFO com.yq.js.JavaJSDemo - result=null11:34:26.253 [main] INFO com.yq.js.JavaJSDemo - result=hello world!11:34:26.253 [main] INFO com.yq.js.JavaJSDemo - ---invokeFunction ---11:34:26.261 [main] INFO com.yq.js.JavaJSDemo - Get msg=hello world!11:34:26.272 [main] INFO com.yq.js.JavaJSDemo - get sum=1511:34:26.280 [main] INFO com.yq.js.JavaJSDemo - func = var result = true; if (msgType.type = 'deviceTelemetryData') {if (msg.temperature >0 && msg.temperature < 33) {result = true ;} else {result = false;} } else {result = false; var errorMsg = msgType.type + ' is not deviceTelemetryData'; print(msgType.type) } return result11:34:26.317 [main] INFO com.yq.js.JavaJSDemo - function result=false11:34:26.317 [main] INFO com.yq.js.JavaJSDemo - ---invokeFunction ---11:34:26.317 [main] INFO com.yq.js.JavaJSDemo - Current dir=D:\E\workspaceGitub\springboot11:34:26.328 [main] INFO com.yq.js.JavaJSDemo - get age=:34:26.328 [main] INFO com.yq.js.JavaJSDemo - function result=null11:34:26.334 [main] INFO com.yq.js.JavaJSDemo - myAdd obj=3.0Process finished with exit code 0

本文转自:russle

/russle/article/details/85214044?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-2.channel_param

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。