使用 Rhino 而不是 ScriptEngine 在 Java 中运行 Javascript 代码

基于在java中将未知日期格式的字符串表示形式转换为日期的讨论,我想在我的App-Engine项目中使用JavaScript函数。但是,ScriptEngine 不适用于 App-Engine。所以我需要一点帮助来转换到犀牛。以下是我需要转换的脚本引擎代码:Date

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;
}

我已经用 和 替换了 ."TestScript"null""


答案 1

在由 JavaScript 引擎执行的脚本中,您只需要计算要使用的值(也可以使用 )。不应将结果存储在变量中。new Date(dateString).getTime()"var date = new Date(dateString); date.getTime()";

我还对你的方法做了两个补充:

  • 要将计算结果转换为字符串,应使用 。由于这里,结果实际上是一个数字,我们可以直接使用,它返回一个,并将其转换为。Context.toString(obj)Context.toNumber(obj)doublelong
  • 我添加了一个从.finallyContext

工作代码:

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测试的。


答案 2

你应该先像这样尝试一下,看看它是否有效:

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));
    }

根据这一点,你接下来需要做的就是像这样传递变量,不需要java字符串串联(上下文足够智能,可能会将java方法的可访问变量视为javascript作用域中的全局变量):dateInUnknownFormat

String script = "var date = new Date(dateInUnknownFormat).getTime();";