现状
我们目前使用一个小程序来执行一些操作,之后它会重定向当前页面。从本质上讲,你可以将这个小程序看作是以下内容:
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 code="com.example.applet.ExampleApplet.class" archive="${appletUrl}" width="100" height="30">
<param name="targetPage" value="http://localhost:8080/applet/"/>
</applet><br/><br/>
${appletUrl}
返回应用程序 JAR 的位置。
因此,该 applet 不过是一个简单的按钮,调用 getAppletContext().showDocument(new URL(target), "_parent");
刷新当前页面。长期以来,它一直能够成功地完成其工作。现在出现了问题。
迁移
众所周知,Chrome 不支持 Applets。然而,由于 IE 和 FireFox 仍然支持它们,此问题被搁置了一段时间。但到了 2016 年底,它们也将停止支持 Applets。因此,我们决定使用 JWS 和 JNLP 迁移该 applet。
对于这个简单的重定向按钮示例的迁移,将生成以下 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>
到目前为止,同样的小程序已经成功部署为
JWS
应用程序。由于它是在浏览器之外执行的,因此可以从任何浏览器中使用。这也有点问题。问题是,代码行
getAppletContext().showDocument(new URL(target), "_parent");
仍然会重定向,但它正在使用默认浏览器,如migration documentation所述。对于AppletContext.showDocument(URL url,String target),Java Web Start技术将忽略target参数。与AppletContext.showDocument类似,Java Web Start应用程序可以使用BasicService.showDocument API使用系统的默认网络浏览器显示HTML页面。
因此,如果我的默认浏览器是FireFox,但我碰巧在IE / Chrome中浏览此启用了JWS的小程序,则将在FireFox中打开一个新标签页。这是一个问题,因为我在原始浏览器中存储了信息(例如登录信息)!
发现:
由于应用程序在浏览器外运行,我很难想到与原始浏览器进行通信的可能性。我不能使用JavaScript,因为它不在浏览器内运行。我也无法定义一个系统独立的方法来打开原始浏览器中的选项卡。我也考虑过WebSockets,因为它们可以直接通信,但据我所读,它非常高级并且需要一个服务器,而不是一个简单的小程序。
是否有可能在小程序打开新窗口时,在原始浏览器之间进行通信(例如WebSockets和参数)或传递会话?