Java 8 Nashorn - capture engine.eval("print('hello world')) into String object?



有没有办法在 Nashorn 中捕获 print('hello world'( 的结果并将其放置在 String 对象中。

我试过这个:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos, true);
System.setOut(ps);
String result = (String)engine.eval("print('hello world')");
if (result != null) {
    System.out.println(result);
} else {
    System.out.println(baos.toString());
}

当引擎评估这个javascript时,它只是打印到stdout,所以我想我只是将stdout重定向到我自己的OutputStream,然后将其转换为字符串,但它不起作用。

有什么想法吗?

您在创建引擎设置System.out流,因此引擎的上下文很可能已经在构建时记录了 System.out/System.err的值。

因此,您仍然会在控制台上看到脚本的输出。更糟糕的是,您不再看到自己的后期System.out.println的输出,因为您已将System.out重定向到ByteArrayOutputStream

因此,不要修改System.out,而是在脚本引擎engine. getContext() . setWriter( stringWriter)的上下文中更改输出。

完整代码:

StringWriter sw=new StringWriter();
engine.getContext().setWriter(sw);
String result = (String)engine.eval("print('hello world')");
System.out.println("Result returned by eval(): "+result);
System.out.println("Captured output: "+sw);

我怀疑问题出在:

if (result != null)

计算 print(...) 语句仍然会给你 print 的返回值,这可能是undefined 。但我的猜测是,你仍然有正确的东西在baos,如果你把你的陈述改为if (false)它会按预期工作。

也就是说,这可能不是最好的方法,具体取决于您要做什么。

你不想强制转换评估结果 - 这将是 JS 未定义的值。为当前脚本上下文设置编写器实例后,将评估通过打印编写的代码。然后从编写器实例中选取累积的字符串。(StringWriter 的 toString 会给你那个 String(。

相关内容

最新更新