现状
我们目前使用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
。由于IE
和FireFox
仍支持他们,因此搁置了一段时间。在2016年底,他们也将不再支持他们。因此,我们决定使用JWS
和JNLP
迁移小程序。
迁移此简单重定向按钮示例会提供以下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和参数)之间进行通信或将会话从一个浏览器传递到另一个浏览器?
答案 0 :(得分:5)
我找到了一个有效的解决方案。
由于applet
失去了与浏览器及其会话的所有连接,因此提供通信的另一种方式是使用WebSockets
或Comet
。就我而言,我使用了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的简单连接。