使用Rhino而不是ScriptEngine在Java中运行Javascript代码
基于讨论将未知日期格式的字符串表示转换为Java中的Date ,我想在我的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"
""
。
在JavaScript引擎执行的脚本中,您只需要使用new Date(dateString).getTime()
计算所需的值(您还可以使用"var date = new Date(dateString); date.getTime()";
)。 您不应将结果存储在变量中。
我还为你的方法增加了两个:
- 要将评估结果转换为String,您应该使用
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测试的。
您应该首先尝试这样,看看它是否有效:
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)); }
根据这一点,接下来需要做的就是传递dateInUnknownFormat
变量,不需要java字符串连接(上下文非常智能,可能将java方法的可访问变量视为javascript范围中的全局变量):
String script = "var date = new Date(dateInUnknownFormat).getTime();";