Использование 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
и ""
.
Ответы
Ответ 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();";