3

有没有办法在 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时,它只是打印到标准输出,所以我想我只是将标准输出重定向到我自己的OutputStream,然后将它转换为字符串,但它不起作用。

有什么想法吗?

4

3 回答 3

5

您在创建引擎之后设置System.out流,因此引擎的上下文很可能已经在构建时记录了/的值。System.outSystem.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);
于 2014-10-13T19:45:48.650 回答
0

我怀疑问题出在:

if (result != null)

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

也就是说,这可能不是执行此操作的最佳方法,具体取决于您要执行的操作。

于 2014-10-13T19:11:10.390 回答
0

您不想强制转换 eval 结果 - 那将是 JS 未定义的值。在为当前 ScriptContext 设置 Writer 实例后,您可以评估通过 print 编写的代码。然后从 Writer 实例中获取累积的字符串。(StringWriter 的 toString 会给你那个字符串)。

于 2014-10-21T03:48:09.347 回答