Подтвердить что ты не робот

Использование Rhino вместо ScriptEngine для запуска кода Javascript в Java

На основе обсуждения преобразования строкового представления неизвестного формата даты в Date в java, я хочу использовать функцию JavaScript Date в моем проекте App-Engine, Однако 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;
}

и я уже заменил "TestScript" на null и "".

4b9b3361

Ответ 1

В script, который выполняется механизмом JavaScript, вам просто нужно вычислить нужное значение с помощью new Date(dateString).getTime() (вы также можете использовать "var date = new Date(dateString); date.getTime()";). Вы не должны хранить результат внутри переменной.

Я также сделал два дополнения к вашему методу:

  • Чтобы преобразовать результат оценки в String, вы должны использовать Context.toString(obj). Поскольку здесь результат на самом деле является числом, мы можем использовать непосредственно Context.toNumber(obj), который возвращает double и отбрасывает его на 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.

Ответ 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));
    }

И в соответствии с this все, что вам нужно сделать, это передать переменную dateInUnknownFormat так, нет необходимости в конкатенации строки java (контекст достаточно умен, чтобы, вероятно, рассматривать доступные Java-методы как глобальные переменные в области javascript):

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