最近项目需要,利用java执行动态语言,首先想到的是支持js。
1.从打印Hello World开始
Java8 引入Nashorn实现javascript调用,比如使用java运行一段js实现“Hello World”打印:
package com.iflytek.research.jsdemo;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class NashornTest {
public static void main(String[] args) {
// 加载nashorn执行引擎
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
try {
engine.eval("var str = ‘Hello World‘;"
+ "print(str);");
} catch (ScriptException e) {
e.printStackTrace();
}
}
}
上述代码成功打印了“Hello World”, 现实场景中,script代码大多来自文件,编辑test.js
var str = ‘Hello World‘;
print(str);
将java读取方式改为从文件加载
// 加载nashorn执行引擎
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
try {
FileReader scriptFile = new FileReader("test.js");
engine.eval(scriptFile);
} catch (ScriptException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
运行后,仍然能正常打印
2.传递参数给javascript代码
可以使用SimpleBindings类来实现参数传递,改写test.js
var str = ‘Hello ‘;
print(str + name);
上述代码name变量就可以使用SimpleBindings来传递,具体实现
// 加载nashorn执行引擎
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
try {
FileReader scriptFile = new FileReader("test.js");
SimpleBindings simpleBindings = new SimpleBindings();
simpleBindings.put("name", "Nashorn");
engine.eval(scriptFile, simpleBindings);
} catch (ScriptException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
再次运行代码 打印
Hello Nashorn
这个参数在js中是全局可见的,比如将它放到函数作用域中也可以正常读取到
var good = function() {
return name + ‘ is Good‘;
}
print(good());
打印结果
Nashorn is Good
3.指定调用的函数
在加载js文件后,可以使用Invocable接口的invokeFunction方法, 修改js文件
var good = function(name) {
print(name + ‘ is Good‘);
}
在给函数传参直接在invokeFunction方法添加参数即可,不再需要使用SimpleBindings
public static void main(String[] args) {
// 加载nashorn执行引擎
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
try {
FileReader scriptFile = new FileReader("test.js");
engine.eval(scriptFile);
Invocable in = (Invocable) engine;
in.invokeFunction("good","Nashorn");
} catch (ScriptException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
如果要传递对象也是妥妥的
var good = function(person) {
print( ‘name: ‘ + person.name);
}
Map<String,Object> person = new HashMap<>();
person.put("name", "nashorn");
in.invokeFunction("good",person);
4.获取js返回值
同样调用invokeFunction
test.js
var getPerson = function() {
var person = {
name : "Zhan San",
age: 18
}
return person;
}
public static void main(String[] args) {
// 加载nashorn执行引擎
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
try {
FileReader scriptFile = new FileReader("test.js");
engine.eval(scriptFile);
Invocable in = (Invocable) engine;
JSONObject personJson =(JSONObject)JSONObject.toJSON(in.invokeFunction("getPerson"));
System.out.println(personJson.toJSONString());
} catch (ScriptException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
这里json引用了fastjson包,执行之后获得结果
{"name":"Zhan San","age":18}
原文地址:https://www.cnblogs.com/ljgeng/p/10179766.html
时间: 2024-11-01 17:20:42