有没有办法在 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(。