使用 Rhino 代替 ScriptEngine 在 Java 中运行 Javascript 代码
Posted
技术标签:
【中文标题】使用 Rhino 代替 ScriptEngine 在 Java 中运行 Javascript 代码【英文标题】:Using Rhino instead of ScriptEngine to run Javascript code in Java 【发布时间】:2016-01-16 12:08:01 【问题描述】:基于converting string representation of unknown date-format to Date in java 的讨论,我想在我的 App-Engine 项目中使用 javascript Date
函数。但是,ScriptEngine 不适用于 App-Engine。所以我需要一些帮助来转换为 Rhino。这是我需要转换的 ScriptEngine 代码:
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine engine = scriptEngineManager.getEngineByName("JavaScript");
String script = "var date = new Date('" + dateInUnknownFormat + "'); var timestamp = date.getTime();";
engine.eval(script);
long timestamp = ((Double) engine.get("timestamp")).longValue();
以下操作无效
private static long parseDateUsingRhino(String dateInUnknownFormat)
Context mozillaJsContext = Context.enter();
Scriptable scope = mozillaJsContext.initStandardObjects();
String script = "var date = new Date('" + dateInUnknownFormat + "'); var timestamp = date.getTime();";
Object obj = mozillaJsContext.evaluateString( scope, script, "TestScript", 1, null );
Double timeDouble = Double.parseDouble((String) obj);
long timestamp = timeDouble.longValue();
return timestamp;
我已经用null
和""
替换了"TestScript"
。
【问题讨论】:
您是否忘记添加错误跟踪? 没有。我把它拿出来,因为它无关紧要。我只是不知道如何正确编写代码。无关紧要是因为我得到不同的错误或没有错误取决于我的尝试。但最终,我永远无法让 Rhino 产生结果。显然,知道 Rhino 是如何工作的人,将 ScriptEngine 版本翻译成 Rhino 是没有问题的。 【参考方案1】:你应该先这样尝试,看看它是否有效:
private static long parseDateUsingRhino(String dateInUnknownFormat)
Context mozillaJsContext = Context.enter();
Scriptable scope = mozillaJsContext.initStandardObjects();
String script = "var date = new Date().getTime();";
Object result = mozillaJsContext.evaluateString( scope, script, "", 1, null );
return Long.valueOf(Context.toString(result));
根据this,您接下来需要做的就是像这样传递dateInUnknownFormat
变量,不需要java 字符串连接(上下文足够聪明,可能会将java 方法的可访问变量视为javascript 中的全局变量范围):
String script = "var date = new Date(dateInUnknownFormat).getTime();";
【讨论】:
我遇到了类似的问题,所以我尝试应用您的解决方案并得到java.lang.NumberFormatException: For input string: "undefined"
。这就是您具有"var date = new Date().getTime();"
的确切代码块
你在发布之前测试过这段代码吗?它不起作用。【参考方案2】:
在 JavaScript 引擎执行的脚本中,你只需要使用new Date(dateString).getTime()
计算你想要的值(你也可以使用"var date = new Date(dateString); date.getTime()";
)。您不应该将结果存储在变量中。
我还对你的方法做了两个补充:
要将评估结果转换为字符串,应使用Context.toString(obj)
。由于这里的结果实际上是一个数字,我们可以直接使用Context.toNumber(obj)
,它返回一个double
,并将其转换为long
。
我添加了一个从Context
退出的finally
块。
工作代码:
private static long parseDateUsingRhino(String dateInUnknownFormat)
Context mozillaJsContext = Context.enter();
try
Scriptable scope = mozillaJsContext.initStandardObjects();
String script = "new Date('" + dateInUnknownFormat + "').getTime()";
Object obj = mozillaJsContext.evaluateString(scope, script, "TestScript", 1, null);
return (long) Context.toNumber(obj);
finally
Context.exit();
示例:
System.out.println(parseDateUsingRhino("2015-10-25T15:06:42.000Z")); // prints 1445785602000
附注:这是用 Rhino 1.7.7 测试的。
【讨论】:
以上是关于使用 Rhino 代替 ScriptEngine 在 Java 中运行 Javascript 代码的主要内容,如果未能解决你的问题,请参考以下文章
使用 ScriptManager (Rhino) 从 Java 中使用 Javascript HTML5 类型数组,如何?