如何在浏览器和Java Web Start applet之间进行通信

时间:2016-06-16 14:43:44

标签: java browser applet java-web-start jnlp

现状

我们目前使用applet执行某些操作,然后重定向当前页面。在其核心中,您可以看到applet如下:

public class ExampleApplet extends Applet {
    @Override
    public void init() {
        Button redirect = new Button("Redirect");
        this.add(redirect);
        final String target = this.getParameter("targetPage");
        redirect.addActionListener((ActionEvent e) -> {
            try {
                getAppletContext().showDocument(new URL(target), "_parent");
            } catch (MalformedURLException ex) {}
        });
    }
}

以最简单的方式调用applet:

<applet code="com.example.applet.ExampleApplet.class" archive="${appletUrl}" width="100" height="30">
    <param name="targetPage" value="http://localhost:8080/applet/"/>
</applet><br/><br/>

其中${appletUrl}返回applet JAR的位置。

所以applet只不过是一个简单的按钮,它调用getAppletContext().showDocument(new URL(target), "_parent");来刷新当前页面。这已经很长时间正确地完成了它的工作。现在问题就在这里。

移植

许多人可能知道,Chrome不支持Applet。由于IEFireFox仍支持他们,因此搁置了一段时间。在2016年底,他们也将不再支持他们。因此,我们决定使用JWSJNLP迁移小程序。

迁移此简单重定向按钮示例会提供以下html代码段和JNLP文件:

<a href="${jnlpUrl}">Launch JNLP</a>

${jnlpUrl}将位置返回到JNLP文件:

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="http://localhost:8080/applet/assets/1.0-SNAPSHOT-DEV/app/assets/" href="jnlp/example.jnlp">
    <security>
        <all-permissions/>
    </security>
    <resources>
        <j2se version="1.5+" initial-heap-size="32m" max-heap-size="128m" />
        <property name="jnlp.versionEnabled" value="false"/>
        <jar href="applets/ExampleApplet.jar" main="true"/>
    </resources>
    <applet-desc name="code" main-class="com.example.applet.ExampleApplet.class" width="30" height="30" >
        <param name="targetPage" value="http://localhost:8080/applet/"/>
    </applet-desc>
</jnlp>

到目前为止,同样的applet成功部署为JWS应用程序。允许从任何浏览器使用它,因为它在它之外执行。这也是一个问题。

问题

getAppletContext().showDocument(new URL(target), "_parent");行仍然会进行重定向,但它使用了migration documentation.

中所述的默认浏览器
  

对于AppletContext.showDocument(URL url,String target),Java Web Start技术将忽略目标参数。

     

与AppletContext.showDocument类似,Java Web Start应用程序可以使用BasicService.showDocument API使用系统的默认Web浏览器显示HTML页面。

因此,如果我的默认浏览器是FireFox,但我正好在IE / Chrome中浏览此JWS-enabled applet,则会在FireFox中打开一个新标签。这是一个问题,因为我在原始浏览器中存储了信息(例如登录)!

首饰

由于应用程序在浏览器之外运行,因此我无法考虑与原始浏览器进行通信的可能性。我无法使用JavaScript,因为它不会在浏览器中运行。我无法真正定义一种独立于系统的方式来打开原始浏览器中的选项卡。我也想过WebSockets,因为它们可以允许直接沟通,但是从我读过它的相当高级别并且需要服务器,而不是简单的小程序。

当applet打开一个新窗口时,是否有可能在原始浏览器(例如websockets和参数)之间进行通信或将会话从一个浏览器传递到另一个浏览器?

2 个答案:

答案 0 :(得分:5)

我找到了一个有效的解决方案。

由于applet失去了与浏览器及其会话的所有连接,因此提供通信的另一种方式是使用WebSocketsComet。就我而言,我使用了Comet Atmosphere框架和Tapestry-Atmosphere实现,因为Tapestry是我正在使用的视图框架。

如果不深入Tapestry实施,我已经做了以下事情:

  • 在客户端浏览器上设置Topic,它将以典型的publish/subscribe方式收听广播的消息。
  • Topic提供当前浏览用户唯一的Applet ID,以及向URL发送请求的Topic。使用Topic ID作为网址的请求参数。
  • 服务器端我有请求的端点,它接收Topic作为请求参数。使用此参数,它会向主题发送广播(可能为空)。
  • 客户端Comet接收通知并自行执行事件。该活动将重新呈现页面的特定内容。

由于它使用WebSockets(但也可以使用Topic),因此它直接在浏览器中发生。每个浏览器实际上都订阅了getAppletContext().showDocument(new URL(target), "_parent");,但这里只有一个。

实际上可以从applet的简单请求更新页面。该小程序仅将new URL(target).openConnection().getInputStream();行更改为target<html-import>是包含请求参数的网址。

答案 1 :(得分:2)

这是旧线程的答案。我们在环境中遇到了类似的情况。这是它的解决方法。

Can an Applet that uses JavaScript to communicate with web server be migrated to JWS?

解决方案与詹姆斯描述的类似。我们在服务器端维护了一个使用uid作为密钥的请求的哈希映射。然后,Web应用程序会长时间轮询服务器以检查JWS状态;和JWS将状态POST到服务器。

我们没有使用任何第三方组件;这是与URL的简单连接。