目录
在Java中,运行或执行JavaScript脚本有几种方式,其中最常用的是通过Java内置的JavaScript引擎(Nashorn或者Rhino)来执行JavaScript代码。下面介绍几种实现方式。
1. 使用ScriptEngine执行JavaScript
Java 在 JDK 6 中引入了javax.script包,这个包允许你在 Java 中使用脚本语言,包括 JavaScript。到 JDK 8 时,Nashorn JavaScript 引擎取代了早期的 Rhino 引擎(jdk6以下版本)。
示例代码:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class JavaScriptExample {
public static void main(String[] args) {
// 创建ScriptEngineManager
ScriptEngineManager manager = new ScriptEngineManager();
// 获取JavaScript引擎
ScriptEngine engine = manager.getEngineByName("JavaScript");
// 要执行的JavaScript代码
String script = "var x = 10; var y = 20; x + y;";
// 执行JavaScript代码
try {
Object result = engine.eval(script);
System.out.println("JavaScript结果: " + result);
} catch (ScriptException e) {
e.printStackTrace();
}
}
}
输出:
JavaScript结果: 30
2. Nashorn(JDK 8及以上)和工具类
在Java 8中,Nashorn引擎是默认的JavaScript引擎。Nashorn的性能比Rhino引擎更好,并且提供了更好的ES5标准的支持。
JDK 8 默认使用 Nashorn。如果你在 JDK 11 或更高版本,Nashorn 可能被删除,推荐使用其他方式(如 GraalVM)。
基于目前大多项目使用jdk8,给出如下详细工具类可供使用。
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class ScriptUtil {
private final ScriptEngine engine;
public ScriptUtil() {
ScriptEngineManager manager = new ScriptEngineManager();
// 获取Nashorn引擎实例
engine = manager.getEngineByName("nashorn");
}
// 执行任意JavaScript代码
public Object executeScript(String script) throws ScriptException {
return engine.eval(script);
}
// 执行带参数的JavaScript代码
public Object executeScriptWithBindings(String script, Object... args) throws ScriptException {
// 设置脚本中的参数
for (int i = 0; i < args.length; i++) {
engine.put("arg" + i, args[i]);
}
return engine.eval(script);
}
// 调用JavaScript中的函数
public Object callFunction(String script, String functionName, Object... args) throws ScriptException, NoSuchMethodException {
// 先执行包含函数定义的脚本
engine.eval(script);
// 获取Invocable实例
Invocable invocable = (Invocable) engine;
// 调用指定的JavaScript函数
return invocable.invokeFunction(functionName, args);
}
public static void main(String[] args) {
try {
//JavaScriptExecutor executor = new JavaScriptExecutor();
ScriptUtil xbScriptUtil = new ScriptUtil();
// 执行简单的JavaScript代码
String script = "print('Hello, World!');";
Object object = xbScriptUtil.executeScript(script);
System.out.println(object);
// 执行带参数的JavaScript代码
String scriptWithParams = "var result = arg0 + arg1; result;";
Object result = xbScriptUtil.executeScriptWithBindings(scriptWithParams, 5, 3);
System.out.println("Result with bindings: " + result);
// 调用JavaScript中的函数
String functionScript = "function add(a, b) { return a + b; }";
Object functionResult = xbScriptUtil.callFunction(functionScript, "add", 5, 3);
System.out.println("Function result: " + functionResult.toString());
String functionScript1 = "function calcData(val) { var val2='455'; return val+val2; }";
//传入字符串
Object functionResult1 = xbScriptUtil.callFunction(functionScript1, "calcData", "222");
System.out.println("Function1 result: " + functionResult1.toString());
String functionScript2 = "function calcData(obj) { var val2=obj.getData('11','22'); return val2; }";
// 传入对象参数,调用函数
Object functionResult2 = xbScriptUtil.callFunction(functionScript2, "calcData", xbScriptUtil);
System.out.println("Function2 result: " + functionResult2.toString());
// System.out.println(xbScriptUtil.getData("1","2"));
} catch (ScriptException | NoSuchMethodException e) {
e.printStackTrace();
}
}
public String getData(String channelId, String pointId) {
return channelId + "#" + pointId;
}
}
输出:
Hello, World!
null
Result with bindings: 8.0
Function result: 8.0
Function1 result: 222455
Function2 result: 11#22
3.GraalVM(JDK 11及以上)
从JDK 11开始,Oracle现代允许删除了Nashorn,引入了GraalVM多语言支持的更完整的方案。GraalVM作为在Java中高效执行JavaScript、Python、R等多种语言。
使用GraalVM执行JavaScript
需要使用GraalVM的polyglotAPI,下面是如何通过GraalVM执行JavaScript代码的示例。
示例代码:
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js</artifactId>
<version>23.0.4</version> <!-- 请使用最新版本 -->
</dependency>
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;
public class GraalVMExample {
public static void main(String[] args) {
// 创建GraalVM上下文
try (Context context = Context.create()) {
// 执行JavaScript代码
Value result = context.eval("js", "var x = 10; var y = 20; x + y;");
System.out.println("JavaScript结果: " + result.asInt());
}
}
}
输出:
JavaScript结果: 30
总结
ScriptEngine (Nashorn/Rhino):适用于JDK 8及以下版本,适合简单的JavaScript脚本执行。
GraalVM:推荐在JDK 11及以上使用,支持更多语言,并且性能更优。
如果你在Java项目中需要集成或执行大量复杂的JavaScript代码,推荐使用GraalVM。如果只需要运行少量简单的JavaScript代码,可以继续使用ScriptEngine。