【问题标题】:Evaluating javascript using a java code使用 java 代码评估 javascript
【发布时间】:2013-03-25 03:25:23
【问题描述】:

这可能不切实际,但我将其作为一项任务。 我在java中有一个打开的ServerSocket。现在我想读取一个包含 html 和 javascript 的文件,并将 javascript 结果输出到浏览器。所以这样,我将在服务器端评估 javascript。所以我想要里面的东西 待评估。

我试过这个来测试,它工作但它有一些问题,例如它将消息打印到 System.out。和 engine.eval("print('Welocme to java worldddd')");不返回字符串,以便我可以将其输出到套接字的输出流:

import javax.script.*;
// create a script engine manager
ScriptEngineManager factory = new ScriptEngineManager();
// create a JavaScript engine
ScriptEngine engine = factory.getEngineByName("JavaScript");
try {
     // evaluate JavaScript code from String
     engine.eval("print('Welocme to java worldddd')");
     //engine.eval("a");
} catch (ScriptException ex) {
     Logger.getLogger(doComms.class.getName()).log(Level.SEVERE, null, ex);
}

【问题讨论】:

标签: java javascript web


【解决方案1】:

您可以通过在 ScriptContext 上设置编写器来获取脚本的输出(在 JavaScript 中使用 print() 打印的内容):

ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
ScriptContext context = engine.getContext();
StringWriter writer = new StringWriter();
context.setWriter(writer);

engine.eval("print('Welocme to java worldddd')");

String output = writer.toString();

System.out.println("Script output: " + output);

【讨论】:

    【解决方案2】:

    我过去通过在 eval() 中创建一个 javascript 函数并调用它来获得结果来解决这个问题:

    import javax.script.*;
    // create a script engine manager
    ScriptEngineManager factory = new ScriptEngineManager();
    // create a JavaScript engine
    ScriptEngine engine = factory.getEngineByName("JavaScript");
    try {
         // evaluate JavaScript code from String
         engine.eval("function sum(a,b){ return a + b;}");
         System.out.println(((Invocable) engine).invokeFunction("sum", new Object[]{10,20}));
    } catch (ScriptException ex) {
         Logger.getLogger(doComms.class.getName()).log(Level.SEVERE, null, ex);
    }
    

    注意invokeFunction(第一个参数)中的函数名应该与之前声明的一致。

    请记住,这可能很危险。您对 javascript 代码的来源有绝对的控制权吗?否则一个简单的while(true){} 对您的服务器来说可能是灾难性的。

    【讨论】:

      【解决方案3】:
      public static String convertEnumToJson(Class<? extends Enum<?>> cls) throws ScriptException, NoSuchMethodException, IllegalAccessException {
          List<Map<String, Object>> map = createMap(Colors.class);
          return createJson(map);
      }
      
      public static List<Map<String, Object>> createMap(Class<? extends Enum<?>> cls) throws IllegalAccessException {
          List<Map<String, Object>> res = new ArrayList<>();
      
          for (Enum<?> item : cls.getEnumConstants()) {
              Map<String, Object> map = new LinkedHashMap<>();
      
              for (Field field : item.getClass().getDeclaredFields()) {
                  if (field.getType() != item.getClass() && !"$VALUES".equals(field.getName())) {
                      field.setAccessible(true);
                      map.put(field.getName(), field.get(item));
                  }
              }
      
              res.add(map);
          }
      
          return res;
      }
      
      // It's better to use Jackson or similar lib for read/write json
      public static <T> String createJson(T obj) throws ScriptException, NoSuchMethodException {
          ScriptEngineManager factory = new ScriptEngineManager();
          ScriptEngine engine = factory.getEngineByName("JavaScript");
          engine.eval("function sum(a){ return a;}");
          return ((Invocable)engine).invokeFunction("sum", obj).toString();
      }
      

      【讨论】:

        【解决方案4】:

        如果最近有人像我一样偶然发现此页面,请注意 Nashorn 已根据 this 被弃用。

        您可以探索其他alternatives

        【讨论】:

          猜你喜欢
          • 2016-12-23
          • 2012-10-25
          • 1970-01-01
          • 1970-01-01
          • 2020-12-15
          • 2018-11-05
          • 1970-01-01
          • 1970-01-01
          • 2013-02-01
          相关资源
          最近更新 更多