【发布时间】:2012-10-19 11:33:58
【问题描述】:
我正在使用 javax.script 包在 Java 应用程序中运行外部 JavaScript 文件。
如何在不使用 Java 代码的情况下将一个 JavaScript 文件导入另一个 JavaScript 文件?
【问题讨论】:
标签: javax.script
我正在使用 javax.script 包在 Java 应用程序中运行外部 JavaScript 文件。
如何在不使用 Java 代码的情况下将一个 JavaScript 文件导入另一个 JavaScript 文件?
【问题讨论】:
标签: javax.script
当您说不使用 java 代码时,我不完全确定您的意思,但这是一个可以工作的纯 javascript(虽然它正在调用 java):
importPackage(java.io);
function loadJs(name, user) {
println("Loading " + name);
var f = new File(name);
var br = new BufferedReader(new FileReader(f));
var line = null;
var script = "";
while((line = br.readLine())!=null) {
script += line;
}
println(script);
eval(script);
hello(user);
}
...当然,前提是我有一个名为(比如 c:/temp/hellouser.js)的文件,其内容如下:
function hello(name) { print('Hello, ' + name); }
我使用 groovy 脚本测试了该脚本:
import javax.script.*;
sem = new ScriptEngineManager();
engine = sem.getEngineByExtension("js");
script1 = """
importPackage(java.io);
function loadJs(name, user) {
println("Loading " + name);
var f = new File(name);
var br = new BufferedReader(new FileReader(f));
var line = null;
var script = "";
while((line = br.readLine())!=null) {
script += line;
}
println(script);
eval(script);
hello(user);
}
""";
engine.eval(script1);
Object obj = engine.get("obj");
Invocable inv = (Invocable) engine;
inv.invokeFunction("loadJs", "c:/temp/hellouser.js", "Nicholas");
输出是:
正在加载 c:/temp/hellouser.js
function hello(name) { print('Hello, ' + name); }
你好,尼古拉斯
我希望这大约是您正在寻找的......
============================ 更新================ ===========
这是一个扩展 Rhino 脚本引擎工厂的清理版本(因为引擎本身是最终版本):
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import com.sun.script.javascript.RhinoScriptEngineFactory;
/**
* <p>Title: LoadEnabledRhinoEngineFactory</p>
* <p>Description: Adding a loadJs function to the standard JS engine</p>
* <p>Company: Helios Development Group LLC</p>
* @author Whitehead (nwhitehead AT heliosdev DOT org)
* <p><code>org.helios.apmrouter.js.LoadEnabledRhinoEngineFactory</code></p>
*/
public class LoadEnabledRhinoEngineFactory extends RhinoScriptEngineFactory {
/** The load script source */
public static final String LOAD_JS =
"importPackage(java.io); " +
"var script = ''; " +
"var ctx = null; " +
"function loadScript(name) { " +
"var f = new File(name); " +
"var br = new BufferedReader(new FileReader(f)); " +
"var line = null; " +
"while((line = br.readLine())!=null) { " +
" script += line; " +
"} " +
"_e_ngine.eval(script);" +
"} ";
/**
* {@inheritDoc}
* @see com.sun.script.javascript.RhinoScriptEngineFactory#getScriptEngine()
*/
@Override
public ScriptEngine getScriptEngine() {
ScriptEngine se = super.getScriptEngine();
Bindings b = se.createBindings();
b.put("_e_ngine", se);
se.setBindings(b, ScriptContext.GLOBAL_SCOPE);
try {
se.eval(LOAD_JS);
} catch (ScriptException e) {
throw new RuntimeException(e);
}
return se;
}
现在,loadScript(fileName) 是引擎的一部分,您可以使用 JS 干净地调用它,例如:
loadScript('c:/temp/hellouser.js');
hello('Nicholas');"
或者正如我在 Java 中测试的那样:
ScriptEngine se = new LoadEnabledRhinoEngineFactory().getScriptEngine();
try {
se.eval("loadScript('c:/temp/hellouser.js'); hello('Nicholas');");
} catch (Exception e) {
e.printStackTrace(System.err);
}
干杯。
【讨论】:
#include 指令。我最终所做的是编写与您的提案类似的内容,并使用eval(loadScript("myscript.js")) 运行它(在全局范围级别)。我认为这是一个丑陋的补丁,所以除非有更优雅的解决方案,否则我会继续使用这种方法。
_e_ngine.eval(script),因为它是在同一引擎的另一个执行 eval (loadScript('c:/temp/hellouser.js'); hello('Nicholas');) 的上下文中执行的吗?