繁体   English   中英

使Javascript函数可用于Java代码

[英]Making A Javascript Function Available To Java Code

问题描述

一个有点人为的例子来说明我的问题。 想象一下,我们有一些javascript函数库已经由前端开发团队每天维护和更新。 具体来说,假设一个这样的函数看起来像这样:

function employeesForStore(store) {
    var dictionary = {
        "downtown": ["Joe", "Mary", "Steve"],
        "uptown": ["Jules", "Vincent", "Matt"],
        // and so on for hundreds of locations
    };
    return dictionary[store];
}

注意:请忽略此功能实现的详细信息。 实际函数可能比简单的JSON字典查找复杂得多,并假设我们不知道有关js函数的任何实现细节。 我们所知道的是它需要一个String参数并返回和字符串数组。

现在我们想在Java代码中利用这个功能。 也就是说,在我们的Java代码中,我们想要“加载”这个函数,然后能够多次调用它,传递String args并接收String[]ArrayList<String>结果。

从搜索SO和谷歌到目前为止,我知道这将涉及使用:

  • javax.script.ScriptEngineManager
  • javax.script.ScriptEngine
  • 也许是scriptEngine.getContext()用于将值传递给函数并接收结果。

我对上面的细节有点模糊,特别是因为我发现的大多数例子都涉及一次运行javascript代码,而不是让javascript函数可用于Java。

我希望看到的示例代码

  1. 假设js函数位于文件“my_functions.js”中,请将该文件加载到Java中,以便所有函数都可以使用。
  2. 调用employeesForStore("downtown")并将其结果存储在名为downtownResults的变量中的本机java String[]List<String>中。
  3. 与2相同,但调用employeesForStore("uptown")并存储在变量uptownResults

您可以使用Rhino API在java中执行JS代码

教程涵盖了所请求的示例。

创建一个接口,充当JavaScript代码的外观

以下是使用Oracle Java 1.7实现中嵌入的Rhino实现的示例:

package demo;
import java.io.*; import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import javax.script.*;

public class StoreData {
  public static interface Stores {
    public String[] employees(String store);
  }

  public static Stores stores() throws IOException, ScriptException {
    ScriptEngineManager sem = new ScriptEngineManager();
    ScriptEngine engine = sem.getEngineByName("JavaScript");
    AtomicReference<Stores> ref = new AtomicReference<>();
    engine.put("ref", ref);
    String adapt = "ref.set("
        + "new Packages.demo.StoreData.Stores({employees:employeesForStore})"
        + ");";
    try (Reader myFns = new FileReader("my_functions.js")) { // TODO encoding
      engine.eval(myFns);
      engine.eval(adapt);
      return ref.get();
    }
  }

  public static void main(String[] args) throws IOException, ScriptException {
    List<String> employees = Arrays.asList(stores().employees("uptown"));
    System.out.println(employees);
  }
}

通过指定接口,我们让Rhino将JavaScript类型强制转换为Java类型(String,String []等)

JRE规范不保证应该提供什么脚本引擎,因此依赖外部引擎可能是明智之举。 我不知道Nashorn是否会改变这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM