Nashorn NativeDate conversion to java.util.Date



在Java 8上使用Nashorn将Javascript Date对象返回给Java时,如下所示:

ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("nashorn");
Object js = engine.eval("new Date();");

通过以下尝试,我得到异常:

  1. Date javaDate = (Date)js;

    jdk.nashorn.api.scripting.ScriptObjectMirror cannot be cast to java.util.Date

  2. Date javaDate = js.to(Date.class);

    Cannot cast jdk.nashorn.internal.objects.NativeDate to java.util.Date

  3. Date javaDate = (Date)ScriptUtils.convert(js.to(NativeDate.class), Date.class);

    Cannot cast jdk.nashorn.internal.objects.NativeDate to java.util.Date

回到Rhino,我只是使用context.jsToJava(nativeDateObj, Date.class);

任何想法我如何可以实际转换这个NativeDate当它返回到Java?

注:如果我执行js.toString(),那么它会给我"[Date 2012-01-01T19:00:00.000Z]"。我想我可以用正则表达式解析它。

将返回的JavaScript对象转换到jdk.nashorn.api.scripting.ScriptObjectMirror上,然后您将能够以"类似map"的方式访问其属性。

ScriptObjectMirror jsDate = (ScriptObjectMirror) engine.eval("new Date();")
long timestampLocalTime = (long) (double) jsDate.callMember("getTime"); 
// yes, js date returns timestamp in local time so you need to adjust it... ;)
int timezoneOffsetMinutes = (int) (double) jsDate.callMember("getTimezoneOffset");
// java.util.Date construcctor utilizes UTC timestamp
Date jDate = new Date(timestampLocalTime + timezoneOffsetMinutes * 60 * 1000);

参见:http://cr.openjdk.java.net/~sundar/jdk.nashorn.api/8u20/javadoc/jdk/nashorn/api/scripting/ScriptObjectMirror.html

然而,如果你打算经常在Java端使用一些"JavaScript类",你可能会发现定义"覆盖"接口以更方便的方式访问JavaScript对象的方法是有用的。请看下面的例子:

public interface JsDateWrapper {
    long getTime();
    int getTimezoneOffset();
    // ...
}
Object jso = engine.eval("new Date();");
JsDateWrap jsDate = ((Invocable) engine).getInterface(jso, JsDateWrapper.class);
Date jDate = new Date(jsDate.getTime() + jsDate.getTimezoneOffset() * 60 * 1000);

同样的问题在这里,解决:

ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("nashorn");
Object js = engine.eval("new java.util.Date();");

我在我的项目中这样做:

retValue = new Date(value.to(Long.class));

最新更新