【问题标题】:Call Java API from javascript on the client (no web service)从客户端的 javascript 调用 Java API(无 Web 服务)
【发布时间】:2016-02-12 18:45:34
【问题描述】:

我需要一种从本地客户端的 javascript 代码中使用 Java API (jar) 的方法。这可以实现吗?如何实现?


上下文

我有一个允许连接到实时信息源的 Java API(jar 文件)。您可以提交查询,例如,打印您将收到的事件:

service.subscribe(query, evt -> print(evt));

出于法律原因,该 API 只能在客户端计算机上使用,因此我无法将其作为 Web 服务从服务器公开。

目标

我想创建一个网页,从 Web 服务获取数据并将其与从本地 Java API 获取的实时信息数据相结合。

我正在使用 Angular 2,但很乐意考虑任何建议。

网络服务

我见过各种类似的问题,但答案往往是:通过 Web 服务公开 API - 这在我的情况下是不可能的

【问题讨论】:

  • 我认为这是不可能的,因为 Java 可以完全访问底层机器的资源,这是 JavaScript 禁止访问的。
  • 你可以在客户端上安装服务器,这样它就不必去外面了:/除此之外,你是硬生生的。你不能通过一堵砖墙给自己编程,你首先需要一个门口。
  • 是的,我想到了,但我不会在每个客户端上安装服务器...我明白你的意思。
  • 您希望人们如何启动应用程序,您希望他们使用浏览器启动 html 页面,还是希望他们打开 jar 文件?
  • 最好只打开一个网页

标签: javascript java


【解决方案1】:

您可以为此使用 java 小程序。

您应该首先制作一个包含对您的方法的调用的小程序:

public class TestApplet extends Applet{

    private ? service = ...;

    public Object subscribe(Object query) {
        return service.subscribe(query, evt -> print(evt));;
    }
}

这个小程序然后可以包含在网页的 html 中:

<script src="https://www.java.com/js/deployJava.js"></script>
<script>
    <!-- applet id can be used to get a reference to the applet object -->
    var attributes = { id:'testApplet', code:'yourpackage.TestApplet', width:1, height:1} ;
    var parameters = {jnlp_href: 'test_applet.jnlp'} ;
    deployJava.runApplet(attributes, parameters, '1.6');
</script>

然后就可以用javascript调用方法了:

var greeting = testApplet.subscribe("Test");

请注意,由于存在安全问题,applet 正在逐步淘汰,但这在受控和嵌入式环境中是可以的。

以下 oracle 教程提供了有关此技术的更多信息:Invoking Applet Methods From JavaScript Code

【讨论】:

  • Applet 被现代浏览器视为存在安全风险。
【解决方案2】:

我能想到的唯一方法是使用 javafx webview:http://docs.oracle.com/javafx/2/webview/jfxpub-webview.htm

基本上:

  • 您可以使用 javafx 创建自己的基于 java 的“webbrowser”
  • 然后您可以将 java api 公开到 webview 中
  • 您可以在webview中打开一个普通的html页面(即http://server.tld/mypage.html)并使用javascript访问api

在 javascript 中,您可以通过检查公开的 api 是否可用来检查网站是否已使用普通浏览器或您自定义的 webview 打开:

类似的java代码:

WebView webView = new WebView();

jfxPanel.setScene(new Scene(webView));
webEngine = webView.getEngine();
webEngine.setJavaScriptEnabled(true);
webEngine.setConfirmHandler(new ModalConfirmDialog(self));


// get the window and pass the required daos
JSObject jsobj = (JSObject) webEngine.executeScript("window");
// pass the dataaccess to the js context
jsobj.setMember("javaapi", getApiInstance());

webEngine.load("http://whatever.tld/mypage.html");

在javascript中:

if(!window.javaapi) {
   alert("Unable to get local java api");
   return;
} 

其他可能性:

  • 小程序:它们无法工作,因为它们需要从与网页相同的来源下载(由于许可限制,您无法使用)
  • JSP/Servlet:不能使用,因为这意味着 api 必须驻留在服务器上(再次受到许可限制)
  • Java Javascript 引擎:您可以直接从 java 中调用 javascript,但是由于您希望在网页中使用 javascript,所以这也不起作用...

【讨论】:

  • 感谢您的回答 - 我知道 webview,但如果用户可以使用他们的“普通”浏览器,我会更喜欢它。
  • 不幸的是,除非使用小程序或服务器端,否则没有有效的方法可以从普通浏览器调用 java - 所有这些都需要您将库分发到服务器上
【解决方案3】:

您无法从 java 脚本运行 .jar 文件(但您可以从 nodejs 执行)您可以使用小程序来执行此操作。可以参考this链接。

【讨论】:

    【解决方案4】:

    这听起来可能很奇怪,但实际上,有这样的工具可以让你从 java '转换' 到 js。但是当然它有它的局限性,为了在你的特殊情况下成功地应用它而不做修改和手鼓跳舞,你应该非常幸运。该工具能够将其转换为 js,并允许您为转换后的 JS 创建一个 JS API,以便可以从其他 js 脚本访问它。我说的是GWT。你必须有一个 jar 的源文件(它可能是反编译的源),包括 lib 使用的所有依赖源。

    【讨论】:

      【解决方案5】:

      也许您可以投资在您的 JS 代码和使用 Nashorn 的 jar 之间建立一座桥梁。

      它允许您评估 JS 代码并从 Java 调用 JS 函数,因此它可以服务于您的用例。您可以构建一个 Java 层以从 jar 连接到 API,然后通过使用 Nashorn 调用某些函数将结果发布到 JS。

      或者你可以利用直接从 JS 调用 Java 函数的能力。

      这是一个简单的tutorial

      【讨论】:

        猜你喜欢
        • 2014-09-04
        • 1970-01-01
        • 1970-01-01
        • 2013-07-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-25
        相关资源
        最近更新 更多