javax.script.ScriptEngine 控制台扩展或库?

标签 java scriptengine

这样我就将 console.log 功能添加到了 javax.script.ScriptEngine 中。

   public class Console {
        public void log(String text){
            System.out.println("console: " + text);
        }
    }

    private static ScriptEngine getJavaScriptEngine(){
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");

    Console console = new Console();
    engine.put("console", console);

    return engine;
     }

因为控制台和警报等不是实现的一部分。经过大量搜索后,我只在这里和其他地方找到了相同的声明,但想知道是否没有一个库可以正确执行此操作?

最佳答案

我有一个类似的解决方案,但发现它不会格式化对象/数组。它也不会处理多个参数(例如 console.log('this is the answer:', 42))。

为了解决这个问题,我必须填充 console。它不支持其所有功能,但可以用于日志记录。要将对象和数组格式化为 JSON,似乎 JSON 对象也不可用 - 因此也必须填充该对象。

可能有一个更漂亮的解决方案,但这个设置让我继续前进:

  1. Polyfill JSON 对象,采用此处提到的脚本:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON#Polyfill 。 Rhino 不知道 window,因此替换:

    if (!window.JSON) {
      window.JSON = {
        // ... rest of code ...
      };
    }
    

    作者:

    // if (!window.JSON) {
      // window.
      JSON = {
        // ... rest of code ...
      };
    // }
    

    将其保存在src/main/resources/scripts/json.js下。

  2. 然后,对于 console 对象,将以下内容放入 src/main/resources/scripts/console.js 中:

    console = {
      _format: function(values) {
        var msg = [];
        for (var i=0;i<values.length;i++)
          msg.push(JSON.stringify(values[i]));
        return msg.join(', ');
      },
      log: function() {
        log.fine(console._format(arguments));
      },
      info: function() {
        log.info(console._format(arguments));
      },
      warn: function() {
        log.warning(console._format(arguments));
      }
    };
    

    请注意,此console实现使用log全局变量。就我而言,这是一个 JUL Logger 实例,但只要有一点创造力,就可以将其更改为使用另一个日志框架(例如 SLF4j)。

  3. 最后,要将所有这些都放在 Java 代码中,可以像这样完成:

    public class ConsoleTest {
    
        public static void main(String... args) throws ScriptException, IOException {
            ScriptEngineManager factory = new ScriptEngineManager();
            ScriptEngine engine = factory.getEngineByName("JavaScript");
    
            engine.put("log", Logger.getLogger("script"));
            run(engine, "/scripts/json.js");
            run(engine, "/scripts/console.js");
    
            engine.eval("console.log('string value');");
            engine.eval("console.warn(['array','value']);");
            engine.eval("console.info({a:1,b:'two'});");
        }
    
        private void run(ScriptEngine engine, String resourceName) throws ScriptException, IOException {
            InputStream in = getClass().getResourceAsStream(resourceName);
            Reader reader = new InputStreamReader(in, Charset.forName("UTF-8"));
            engine.eval(reader);
            reader.close();
        }
    
    }
    

关于javax.script.ScriptEngine 控制台扩展或库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38079894/

相关文章:

Java机器人类在笔记本电脑上工作但在电脑上不工作

java - 如何从java中递归生成的结果列表中返回特定结果

java - Hibernate Envers仅使用servlet保存用户名

javascript - 基于 ScriptEngine 'javascript' 进行不正确的正则表达式验证(对于 IP 地址)

java - 如何从外部停止从主要方法运行的 quartz 调度程序

java - Tuckey - URL 重定向有效但转发无效

c# - 限制在 MS 脚本引擎中使用命名空间

java - 从 Java 执行时,R 脚本无法读取 .Rda 文件

java - 将 Jruby ScriptEngine 输出重定向到 StringWriter

java - ScriptEngine 清除和处置