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

Jai*_*ims 7 java browser jnlp applet java-web-start

现在的情况

我们目前使用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) {}
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

以最简单的方式调用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/>
Run Code Online (Sandbox Code Playgroud)

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

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

移民

众所周知,Chrome不支持Applets.从那时起搁置一段时间IEFireFox仍然支持他们.在2016年底,他们也将不再支持他们.所以我们决定使用JWS和迁移applet JNLP.

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

<a href="${jnlpUrl}">Launch JNLP</a>
Run Code Online (Sandbox Code Playgroud)

${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>
Run Code Online (Sandbox Code Playgroud)

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

问题

该行getAppletContext().showDocument(new URL(target), "_parent");仍然进行重定向,但它使用迁移文档中所述的默认浏览器.

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

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

因此,如果我的默认浏览器是FireFox,但我碰巧JWS-enabled applet在IE/Chrome中浏览到这个,则会在FireFox中打开一个新选项卡.这是一个问题,因为我有原始浏览器中存储的信息(例如登录)!

发现

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

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

Jai*_*ims 5

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

由于applet丢失了与浏览器及其会话的所有连接,因此提供通信的另一种方式是WebSocketsComet.在我的情况下,我使用CometAtmosphere框架和Tapestry-Atmosphere实现,因为Tapestry是视图的框架我使用.

在不深入Tapestry实施的情况下,我做了以下工作:

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

由于它正在使用Comet(但也可以使用WebSockets),它直接在浏览器中发生.每个浏览器Topic实际上都订阅了,但这里只有一个.

实际上可以从applet的简单请求更新页面.小程序只getAppletContext().showDocument(new URL(target), "_parent");更改了行new URL(target).openConnection().getInputStream();.使用target包含请求参数的URL.