在Java中运行Javascript代码,使用Rhino代替ScriptEngine

21

基于这个讨论 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"

Translated:

and I have already replaced "TestScript" with null and "".


你忘记添加错误跟踪了吗? - Filip
1
不,我把它拿掉了,因为它与问题无关。我只是不知道如何正确编写代码。这种无关性是由于我尝试的不同方法会导致不同的错误或没有错误。但最终,我始终无法让Rhino产生结果。显然,熟悉Rhino工作原理的人将毫不费力地将ScriptEngine版本转换为Rhino。 - learner
2个回答

1
在由JavaScript引擎执行的脚本中,您只需要使用new Date(dateString).getTime()(也可以使用"var date = new Date(dateString); date.getTime()";)计算所需的值。不应将结果存储在变量中。
我还对您的方法进行了两个添加:
  • 要将评估的结果转换为字符串,您应该使用Context.toString(obj)。由于此处结果实际上是一个数字,因此我们可以直接使用返回doubleContext.toNumber(obj)并将其强制转换为long
  • 我添加了一个finally块,用于退出Context
工作代码:
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进行测试的。


0

你应该先尝试这样做,看看是否有效:

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();" 的时候。 - Katedral Pillon
你在发布前测试过这段代码吗?它不起作用。 - learner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接