从 java 代码调用外部 javascript 函数

Posted

技术标签:

【中文标题】从 java 代码调用外部 javascript 函数【英文标题】:Call external javascript functions from java code 【发布时间】:2014-05-16 09:10:31 【问题描述】:

通过使用 Java Scripting API,我能够在 Java 中执行 javascript。但是,有人可以解释一下我需要添加到此代码中以便能够调用 C:/Scripts/Jsfunctions.js 中的函数

import javax.script.*;

public class InvokeScriptFunction 
public static void main(String[] args) throws Exception 
    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("JavaScript");

    // JavaScript code in a String
    String script1 = "function hello(name) print ('Hello, ' + name);";
    String script2 = "function getValue(a,b)  if (a===\"Number\") return 1; 
                     else return b;";
    // evaluate script
    engine.eval(script1);
    engine.eval(script2);

    Invocable inv = (Invocable) engine;

    inv.invokeFunction("hello", "Scripting!!");  //This one works.      
 

【问题讨论】:

【参考方案1】:

使用ScriptEngine.eval(java.io.Reader)阅读脚本

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
// read script file
engine.eval(Files.newBufferedReader(Paths.get("C:/Scripts/Jsfunctions.js"), StandardCharsets.UTF_8));

Invocable inv = (Invocable) engine;
// call function from script file
inv.invokeFunction("yourFunction", "param");

【讨论】:

是的,它很有用,谢谢。我们如何在提供的 javascript 中使用 Window,因为通过 java 代码将没有浏览器。 你指的是哪个窗口或浏览器? 解决方案是什么? 如果在加载相对路径时遇到困难,请使用下面的代码。 URL fileUrl = getClass().getResource("js/WebWorker.js"); engine.eval(Files.newBufferedReader(Paths.get(fileUrl.toURI()),StandardCharsets.UTF_8)); 嗨,我有疑问,我试图调用具有moment.js库依赖项的函数。所以我只是添加了库脚本以及像这样engine.eval(Files.newBufferedReader(Paths.get("/Volumes/Bala/Eclipse Mars/Workspace/ClientWebAccessFullHistory/war/js/Library/Moment.js"), StandardCharsets.UTF_8)); engine.eval(Files.newBufferedReader(Paths.get("/Volumes/Bala/Eclipse Mars/Workspace/ClientWebAccessFullHistory/war/js/newLayout/FullHistory/fullHistory.js"), StandardCharsets.UTF_8)); 但它在全局范围内不可用。【参考方案2】:
try 
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");
        System.out.println("okay1");
        FileInputStream fileInputStream = new FileInputStream("C:/Users/Kushan/eclipse-workspace/sureson.lk/src/main/webapp/js/back_end_response.js");
        System.out.println("okay2");
        if (fileInputStream != null)
         BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream));
         engine.eval(reader);
         System.out.println("okay3");
        // Invocable javascriptEngine = null;
         System.out.println("okay4");
        Invocable invocableEngine = (Invocable)engine;
         System.out.println("okay5");
         int x=0;
         System.out.println("invocableEngine is : "+invocableEngine);
         Object object = invocableEngine.invokeFunction("backend_message",x);

         System.out.println("okay6");
        
        catch(Exception e) 
            System.out.println("erroe when calling js function"+ e);
        

【讨论】:

感谢您提供此代码 sn-p,它可能会提供一些有限的即时帮助。 proper explanation would greatly improve its long-term value 通过展示为什么这是一个很好的解决问题的方法,并将使其对未来有其他类似问题的读者更有用。请edit您的回答添加一些解释,包括您所做的假设。【参考方案3】:

假设您的 jsfunctions.js 文件有一个“显示”函数,并且该文件存储在 C:/Scripts/Jsfunctions.js 中

jsfunctions.js

var display = function(name) 
print("Hello, I am a Javascript display function",name);
return "display function return"

现在,在您的 java 代码中,我建议您使用 Java8 Nashorn。 在你的 java 类中,

import java.io.FileNotFoundException;
import java.io.FileReader;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

class Test 
public void runDisplay() 
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
try 
  engine.eval(new FileReader("C:/Scripts/Jsfunctions.js"));
  Invocable invocable = (Invocable) engine;
  Object result;
  result = invocable.invokeFunction("display", helloWorld);
  System.out.println(result);
  System.out.println(result.getClass());
   catch (FileNotFoundException | NoSuchMethodException | ScriptException e) 
    e.printStackTrace();
    
  

注意:获取 javascript 文件的绝对路径并在 FileReader() 中替换并运行 java 代码。它应该可以工作。

【讨论】:

仅供参考...对于那些由于 Oracle 的 Java 许可变更或任何原因而迁移到 OpenJDK 的人,Nashorn 在 OpenJDK 中已被弃用。 openjdk.java.net/jeps/335

以上是关于从 java 代码调用外部 javascript 函数的主要内容,如果未能解决你的问题,请参考以下文章

javascript 在angular 5中调用外部java脚本函数

从外部接口调用JavaScript

从 javascript 适配器调用 java 代码时出错

从react typescript组件调用外部Javascript函数

从 javascript 适配器调用 java 代码

从java调用包含'const'的javascript?