Java Lodash模板引擎Nashorn

Java Lodash模板引擎Nashorn,java,lodash,nashorn,Java,Lodash,Nashorn,我目前正在尝试使用nashorn在Java中使用lodash模板引擎,我面临一个问题 代码如下: ScriptEngineManager mgr = new ScriptEngineManager(); ScriptEngine nashorn = mgr.getEngineByName("nashorn"); ScriptContext ctx = nashorn.getContext(); Bindings bindings = ctx.getBindings(ScriptContext.E

我目前正在尝试使用nashorn在Java中使用lodash模板引擎,我面临一个问题

代码如下:

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine nashorn = mgr.getEngineByName("nashorn");
ScriptContext ctx = nashorn.getContext();
Bindings bindings = ctx.getBindings(ScriptContext.ENGINE_SCOPE);
nashorn.eval(readFileToString("externallibs/lodash.min.js"), bindings);
String tpl = readFileToString("hello.tpl");
bindings.put("tpl", tpl);
nashorn.eval("compiled = _.template(tpl);", bindings);
ScriptObjectMirror compiled = (ScriptObjectMirror)nashorn.get("compiled");
System.out.println("compiled = " + compiled);
Map<String, String> props = new HashMap<String, String(1);
props.put("name", "world");
bindings.put("props", props);
System.out.println(compiled.call(this, bindings.get("props"));
但是,当我试图用map作为参数(props)调用上面编译的模板函数时,正如您在JS中所做的那样:

调用(this,{name:'world'})

它失败,出现以下错误:


TypeError:无法将“with”应用于非脚本对象

事实上,我们可以看到该函数的编译版本使用了“with”关键字

有人知道如何解决这个问题吗?我应该如何发送参数来呈现已编译的模板


非常感谢您的帮助。

您需要将JS脚本对象传递给“with”语句。任意Java对象(不是JS对象-例如Java.util.Vector或类Foo的对象)不能用作“with”表达式。您可以使用以下代码创建一个空脚本

Object emptyScriptObj = engine.eval("({})");

并将EmptyScriptObjectJ传递给ScriptObjectMirror.call方法调用,例如。

若要使用Java映射作为“with”语句的作用域表达式,可以使用如下内容:

import javax.script.*;
import java.util.*;

public class Main {
  public static void main(String[] args) throws ScriptException {
      Map<String, Object> map = new HashMap<>();
      map.put("foo", 34);
      map.put("bar", "hello");

      ScriptEngineManager m = new ScriptEngineManager();
      ScriptEngine e = m.getEngineByName("nashorn");
      // expose 'map' as a variable
      e.put("map", map);

      // wrap 'map' as a script object
      // __noSuchProperty__ hook is called to look for missing property
      // missing property is searched in the map
      e.eval("obj = { __noSuchProperty__: function(name) map.get(name) }");

      // use that wrapper as scope expression for 'with' statement
      // prints 34 and hello from the map
      e.eval("with (obj) { print(foo); print(bar); }");
   }
}
import javax.script.*;
导入java.util.*;
公共班机{
公共静态void main(字符串[]args)引发脚本异常{
Map Map=newhashmap();
地图.put(foo,34);;
地图。放(“酒吧”、“你好”);
ScriptEngineManager m=新ScriptEngineManager();
ScriptEngine e=m.getEngineByName(“nashorn”);
//将“map”作为变量公开
e、 放("地图",地图);;
//将“映射”包装为脚本对象
//调用\uuuuNoSuchProperty\uuuuuuuuuuuuuuu钩子查找缺少的属性
//在映射中搜索缺少的属性
e、 eval(“obj={{uuuuunosuchproperty}:函数(名称)map.get(名称)}”);
//将该包装器用作“with”语句的范围表达式
//从地图上打印34和hello
e、 eval(“带(obj){print(foo);print(bar);}”);
}
}

谢谢您的回答。我发现这就是失败的原因。但我找不到合适的解决方案来将Java HashMap(props)作为ScriptEngineMError对象注入。你有什么想法吗?再次感谢。如果我没弄错的话,我想一个支架不见了。但我会尝试一下这个解决方案。非常感谢你的回答。
import javax.script.*;
import java.util.*;

public class Main {
  public static void main(String[] args) throws ScriptException {
      Map<String, Object> map = new HashMap<>();
      map.put("foo", 34);
      map.put("bar", "hello");

      ScriptEngineManager m = new ScriptEngineManager();
      ScriptEngine e = m.getEngineByName("nashorn");
      // expose 'map' as a variable
      e.put("map", map);

      // wrap 'map' as a script object
      // __noSuchProperty__ hook is called to look for missing property
      // missing property is searched in the map
      e.eval("obj = { __noSuchProperty__: function(name) map.get(name) }");

      // use that wrapper as scope expression for 'with' statement
      // prints 34 and hello from the map
      e.eval("with (obj) { print(foo); print(bar); }");
   }
}