<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML> <HEAD> <TITLE>Index testing JRE level</TITLE> </HEAD> <BODY> <SCRIPT LANGUAGE="JavaScript"> var javawsInstalled = 0; var javaws12Installed = 0; var javaws142Installed=0; isIE = "false"; if (navigator.mimeTypes && navigator.mimeTypes.length) { x = navigator.mimeTypes['application/x-java-jnlp-file']; if (x) { javawsInstalled = 1; javaws12Installed=1; javaws142Installed=1; } } else { isIE = "true"; } </SCRIPT> <SCRIPT LANGUAGE="VBScript"> on error resume next If isIE = "true" Then If Not(IsObject(CreateObject("JavaWebStart.isInstalled"))) Then javawsInstalled = 0 Else javawsInstalled = 1 End If If Not(IsObject(CreateObject("JavaWebStart.isInstalled.2"))) Then javaws12Installed = 0 Else javaws12Installed = 1 End If If Not(IsObject(CreateObject("JavaWebStart.isInstalled.1.4.2.0"))) Then javaws142Installed = 0 Else javaws142Installed = 1 End If End If </SCRIPT> <SCRIPT LANGUAGE="JavaScript"> if (javawsInstalled || (navigator.userAgent.indexOf("Gecko") !=-1)) { document.write("<a href=test.jnlp>Press here to launch PMSAAS using JWS</a>"); } else { document.write("WebStart is not Installed, Click "); document.write("<a href=http://java.sun.com/j2se/1.4.2/download.html>here</a> "); document.write("to download and install JRE 1.4.2 and try to run the app again."); } </SCRIPT> </BODY> </HTML>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML> <HEAD> <TITLE>Index testing JRE level</TITLE> </HEAD> <BODY> <SCRIPT LANGUAGE="JavaScript"> var javawsInstalled = 0; var javaws12Installed = 0; var javaws142Installed=0; isIE = "false"; if (navigator.mimeTypes && navigator.mimeTypes.length) { x = navigator.mimeTypes['application/x-java-jnlp-file']; if (x) { javawsInstalled = 1; javaws12Installed=1; javaws142Installed=1; } } else { isIE = "true"; } </SCRIPT> <SCRIPT LANGUAGE="VBScript"> on error resume next If isIE = "true" Then If Not(IsObject(CreateObject("JavaWebStart.isInstalled"))) Then javawsInstalled = 0 Else javawsInstalled = 1 End If If Not(IsObject(CreateObject("JavaWebStart.isInstalled.2"))) Then javaws12Installed = 0 Else javaws12Installed = 1 End If If Not(IsObject(CreateObject("JavaWebStart.isInstalled.1.4.2.0"))) Then javaws142Installed = 0 Else javaws142Installed = 1 End If End If </SCRIPT> <SCRIPT LANGUAGE="JavaScript"> if (javawsInstalled || (navigator.userAgent.indexOf("Gecko") !=-1)) { document.write("<a href=test.jnlp>Press here to launch PMSAAS using JWS</a>"); } else { document.write("WebStart is not Installed, Click "); document.write("<a href=http://java.sun.com/j2se/1.4.2/download.html>here</a> "); document.write("to download and install JRE 1.4.2 and try to run the app again."); } </SCRIPT> </BODY> </HTML>
JRE 1.4 中的新特征 Java Web Start 允许您从诸如 WebSphereApplication Server 这样的服务器中部署客户端 J2EE应用程序。本文描述了如何利用 Java Web Start 和 WebSphere Studio使应用程序能够分布在整个浏览器 HTTP连接上,这样它们就可以在客户端本地运行。
当构建分布式应用程序时需要解决的问题之一是,确保软件的各个不同的部分在进行更改和创建新的版本的情况下保持步调一致。解决这个问题的一个办法是简单地完全避免它,并且只是根据需要来分发软件。HTML 基本上使用这种拓扑,在这种拓扑中,客户端没有实际的软件,而是使用浏览器来进行到服务器的 HTTP 连接,并且将返回的 HTML数据解释为它可以呈现给用户的标记页。HTML 数据只是在它请求了页面之后才返回到客户端,并且在使用JSP 或 Servlet 这样的动态环境中,这种安排类似于通过订单来订做的快餐--用户提出请求,开始制做,然后提供给用户。
对于应用程序的管理员,当需要更新时,必须将新的代码完全地载入服务器并且有效地更新所有的客户端。在下次他们请求页面时,就将得到最新的版本。这种只在一个地方更新所有软件的优势大概是目前浏览器在分布式计算环境中普遍存在的最重要的原因。由于首先创建的是 Servlet(准备 HTML 页面的服务器端 Java 程序),所以这一安排并没有多大的改变。JSP 是编写 Servlet 的一种不同的方式,而标签库、JSTL、和 JavaServer Face是使编程模型更容易的全部方式。XUL 和 CSS 将页面数据从它的表示标记中分离开来,但支持它们的基本思想都是它们为客户端准备浏览器中呈现的HTML。
本文描述了 JRE 1.4 引入的一种技术 Java Web Start(JWS),它使 Java 应用程序能够分布在整个 HTTP 连接上,这样它们就可以在客户端上本地运行。
JWS 是作为 JSR-56的一部分而创建的,目的是提供一种方法来分发在客户端上的JVM 中运行的 Java 应用程序。JWS 包括以下特征:
main(String[] args)
方法启动。
如果您有 JRE 1.4.1 或更新的版本,那么您已经安装了 Java Web Start。如果您没有 JRE 1.4.1 或更新的版本,可以从 Sun 下载页面下载并安装 JRE。
与介绍 GUI编程的新方法的文章的传统一样,第一步是创建 Web启动应用程序,它显示带有“HelloWorld”的对话框:这分两步进行:首先创建类并将其部署在Web 服务器中,接着客户端个人计算机访问该 URL,这样就可以通过 JWS下载和调用它。
下面详细地描述这些步骤:
以下是源代码:
import javax.swing.*; public class HelloWorld { public static void main(String[] args) { JFrame frame = new JFrame("Hello World"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(200,100); frame.show(); } } |
当通过 RunAs => JavaApplication执行时,会显示以下 GUI:
通过 RunAs => Application运行应用程序允许您测试应用程序,不过,它是通过在与 WebSphere Studio相同的机器上创建 JVM 并在其中运行程序来做到这一点的。对于 JWS,下一步就是使用 .jnlp文件,并将 HelloWorld 类部署到 WebSphere应用程序服务器的实例,这样就可以通过另一台个人计算机上的浏览器连接来运行它了。
创建动态Web 项目的目的是创建和部署 JWS 应用程序:选择 File => menu或工具栏上的 New下拉列表:
将该项目命名为JavaWebStartTest。该项目中需要 HelloWorld类,因此从最初它的项目中将其作为 JAR文件导出,然后导入 JavaWebStartTest 项目。右键单击 HelloWorld.java,选择 Export =>JAR file,再指定文件系统中的一个位置。然后通过选择 File => Import将 JAR 文件导入 JavaWebStartTest 项目。
如果您更改了 HelloWorld.java,并且想把它重新部署到 Web项目,您可以将其重新作为 JAR文件导出,然后把它再次导入到JavaWebStartTest 项目中。为了简化此项任务,您可以 下载 zipCreation 实用程序,它允许您将项目配置成自动将 JAR导入另一个项目。
下一步是创建 jnlp文件,该文件用于下载和启动 HelloWorld 类。将此文件命名为HelloWorld.jnlp 并将其放在项目的 WebContent 目录中。没有 jnlp 文件向导,因此选择 File => New => Other,然后选择 Simple => File来指定文件名 HelloWorld.jnlp。jnlp 文件由带有许多标记的 XML组成,如下所示。jnlp 标记 [1]指定代码库,代码库是将要运行的代码所在的位置。在本例中,我们将把它硬编码成Web服务器的 URL(在这种情况下就是我的 IP 地址)、端口号和 Web项目的名称。下一部分将向您展示如何使用 Servlet来避免硬编码 Web服务器 URL,但是对于这个简单的示例,可以显式地设置它。
信息标记 [2]指定一些细节,比如应用程序的标题、厂商和一些描述,当用户下载和调用应用程序时这些细节将展示给用户,而在JWS 管理控制台中也同样如此。标记 <offline-allowed> 指定,一旦应用程序通过 JWS下载并本地缓存,您是否就可以从客户端重新启动它而无需连接。标记 <offline-allowed=false>禁用这种功能。对于在客户端中运行的应用程序,指定它所需的JRE 级别来运行 [3] (在我们的示例中为 1.3或更高)、包含应用程序 [4] 的 JAR 文件以及将通过它的 main(String[] args) 方法 [5]运行的 Java 类。jnlp 标记的可选属性是 href="HelloWorld.jnlp"。通过指定这个属性并且指向 jnlp文件本身,HelloWorld应用程序将可以从客户端的管理应用程序中进行访问(如下面的 管理客户端中所述)。
<?xml version="1.0" encoding="utf-8"?> [1] <jnlp spec="1.0+" codebase="http://9.20.217.67:9080/JavaWebStartTest/" [6]href="HelloWorld.jnlp"> [2] <information> <title>HelloWorld</title> <vendor>IBM - JWS example of HelloWorld</vendor> <description>HelloWorld - Example of JWS</description> <description kind="short">HelloWorld example</description> <offline-allowed/> </information> <resources> [3] <j2se version="1.3+"/> [4] <jar href="HelloWorld.jar"/> </resources> [5] <application-desc main-class="HelloWorld"/> </jnlp> |
JAR 文件 [4] 的位置是相对于 jnlp标记 [1]中指定的代码库的。这是 jnlp 文件的完整语法。本文将仅仅描述最常用的标记。其他的标记允许您一些细节,比如应用程序闪屏(splashscreen)和所需的任何安全性许可。下面将介绍安全性,但是现在,HelloWorld类不需要访问磁盘或任何 I/O服务,因而也就不需要安全性许可。
HelloWorld.jnlp文件现在指向 HelloWorld.jar。要帮助启动发行 jnlp文件,可以一个 index.html页面,其下带有一个指向该文件的链接,从而允许用户点击链接来下载文件并通过 JWS 启动 HelloWorld:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML> <HEAD> <TITLE>index.html</TITLE> </HEAD> <BODY> [1] <A href="HelloWorld.jnlp">Launch HelloWorld using JWS</A> </BODY> </HTML> |
下面显示了 Web项目中三个文件的位置。因为 HelloWorld.jnlp 位于 JavaWebStartTest项目的 WebContent 文件夹中,所以已配置的 EAR 代码库将是 ServerURL/JavaWebStartTest。对于 WebSphere Test Environment,服务器 URL 是机器的 name:port号:
在运行应用程序之前,对于服务器需要完成的最后一个步骤是: 关联文件扩展名.jnp与应用程序 MIME 类型 application/x-java-jnlp-file。为了达到这个目的,可以通过单击弹出菜单中的 Open来选择 Servers 视图中的服务器并编辑它的配置。选择 Web选项卡,单击 Add输入 jnlp 扩展的 MIME类型,如下所示。如果您没有已配置好的服务器,就可以从Servers 视图中的弹出菜单选择 New => Server和 ServerConfiguration,然后选择 WebSphere Version 5.0和 Test Environment:
要测试 HelloWorld 应用程序,可以在测试环境中运行index.html:右键单击 Project Navigator 中的文件并选择选择 Run on Server。如果有多个已配置好的服务器,就需要确保带有 jnlp 的 MIME类型扩展的服务器是已启动的服务器。一旦测试环境启动,就可以选择 index.html页面中的链接来将 HelloWorld.jnlp 下载到客户端浏览器。在下面的屏幕截图中,浏览器是嵌入在 WebSphere Studio中的,因此同一个机器既作为(运行 WebSphere TestEnvironment)又作为客户端(运行浏览器)。在以这种方式测试完 jnlp文件之后,转向不是运行 WTE的服务器,并且尝试使用完整的URL(而不是本地主机)从该服务器访问 jnlp 文件,例如 http://9.20.217.67:9080/JavaWebStartTest/index.html。
如果应用程序MIME类型未指定,就将仅仅以文本文件的形式在浏览器中显示jnlp 文件。如果 MIME 类型已经指定,浏览器就将运行 JWS并读取 HelloWorld.jnlp。应用程序第一次运行时,闪屏将会显示它正在下载新的程序,如下所示:
在下载完应用程序之后,JWS会显示关于应用程序的标题和厂商的细节,也会同时显示它下载 JAR文件的进程栏,缓存它然后进行执行。
由于<jnlp> 标记中的 http 属性,所以 HelloWorld 应用程序安装在JWS Application Manager中,并且系统将询问您是否在桌面上安装程序的快捷方式。如果您单击No,以后您还总能够从 Application Manager 创建快捷方式。
最后的结果是 HelloWorld.class将启动。这个应用程序会运行在把自身标识为 Java Application Window 的窗口中,如下所示,这样就可以通过底部的状态行消息将伪装成其他程序的特洛伊木马(TrojanHorse)应用程序标识为来自 JWS。如果 jnlp文件使用的是通过认证签署的 JAR文件,状态消息就不会显示出来。详细信息请下面的 安全性。
在客户端下载和运行 HelloWorld应用程序之后,它会保留本地副本。您可能会注意到随后尝试运行应用程序会更快,并且您只得到一个单独的闪屏而不是前面一序列的启动对话框。
作为jnlp 文件的作者,在通过 JWS启动应用程序时,您可以指定您想与应用程序一起使用的闪屏。通过<information> 标记内的 jnlp 文件中的 <icon>标记可以这样做;属性 kind是值“splash”和指向与 jnlp 代码库相关的 GIF 或 JPG文件的位置的 href。
<icon kind="splash" href="mySplashScreen.gif"/> |
像闪屏一样,如果应用程序安装在桌面上,您还可以在应用程序管理器中指定JWS 所用的 32 * 32 图标。
<icon href="smallIcon.jpg"/> |
应用程序管理器允许客户端个人计算机管理它们所有的JWS 应用程序。程序 javaws.exe 位于 JRE 下的 javaws目录中,例如“ C:\Program Files\Java\j2re1.4.2\javaws\javaws.exe
”。您还可以从下面的 URL 获得它,它本身是 Sun上 JWS 支持的应用程序管理器版本。
因为href="HelloWorld.jnlp" 属性是在 <jnlp>标记中指定的,所以应用程序会在应用程序管理器中列出。如果没有使用 href属性,客户端应用程序就不会包括在应用程序管理器中,系统也不会提示用户快捷方式。所用的图标是在jnlp 文件中的 <icon href="">标记内指定的图标,而如果没有在 HelloWorld.jnlp中进行指定,则缺省的咖啡杯就会显示出来。要在桌面上安装应用程序的快捷方式,可以使用菜单选项 Application => Create shortcuts,它将设置一个桌面图标,这样您就直接启动 HelloWorld,而不用通过Web 浏览器这样做。所用的是在 jnlp 文件内的 <iconhref=""/> 标记中指定的,缺省设置为 Java咖啡杯标志。
您也可以使用菜单选项 Application => Remove shortcuts来删除快捷方式,而菜单选项 Application => Remove application删除本地安装的程序。要控制 JWS应用程序是否作为桌面快捷方式自动安装,您可以选择 File => Preferences,然后打开 Shortcuts选项卡。Preferences对话框还允许让您配置细节,比如您是否通过代理服务器进行连接。
我们前面创建的index.html文件假定客户端浏览器已安装 JWS。如果客户端个人计算机有 JRE 1.4.1 或更高版本,则 JWS 就应该缺省安装了,但是在像因特网这样的环境中,不能假定所有的客户端都处于特定的JRE 级别。为了解决这个问题,可以编写一段 Java 脚本来检测JWS 是否安装并且提示用户是否下载并安装它。对这样的脚本的描述在位于 Sun 的JWS 文件中。下面的文件展示了可以如何重新编写 index.html来自动检测客户端是否有正确的 JRE 层次和JWS 是否安装以及是否提示用户提示下载它。第一步 [1]是查看浏览器是 Netscape还是 IE,如果是 Netscape,就检查 mime 类型来查看 JWS是否安装。VBScript [2] 的第二部分运行在 IE上,而通过使用作为 Web 启动 DLL 的一部分的 COM对象,它尝试检测 JWS 目前的版本(如果它存在的话)。JavaScript [3]的最后的一部分或者将页面链接到 .jnlp文件,或者提示用户通过链接从 Sun 的 Web 站点下载和获取 JRE 1.4.2。indexTestingJreLevel.html文件包括这个 HTML 和下面所展示的 JavaScript,它在本文所附带的可下载 EAR文件中。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML> <HEAD> <TITLE>Index testing JRE level</TITLE> </HEAD> <BODY> [1]<SCRIPT LANGUAGE="JavaScript"> var javawsInstalled = 0; var javaws12Installed = 0; var javaws142Installed=0; isIE = "false"; if (navigator.mimeTypes && navigator.mimeTypes.length) { x = navigator.mimeTypes['application/x-java-jnlp-file']; if (x) { javawsInstalled = 1; javaws12Installed=1; javaws142Installed=1; } } else { isIE = "true"; } </SCRIPT> [2]<SCRIPT LANGUAGE="VBScript"> on error resume next If isIE = "true" Then If Not(IsObject(CreateObject("JavaWebStart.isInstalled"))) Then javawsInstalled = 0 Else javawsInstalled = 1 End If If Not(IsObject(CreateObject("JavaWebStart.isInstalled.2"))) Then javaws12Installed = 0 Else javaws12Installed = 1 End If If Not(IsObject(CreateObject("JavaWebStart.isInstalled.1.4.2.0"))) Then javaws142Installed = 0 Else javaws142Installed = 1 End If End If </SCRIPT> [3]<SCRIPT LANGUAGE="JavaScript"> if (javawsInstalled || (navigator.userAgent.indexOf("Gecko") !=-1)) { document.write("<a href=HelloWorld.jnlp>Press here to launch Hello World using JWS</a>"); } else { document.write("WebStart is not Installed, Click "); document.write("<a href=http://java.sun.com/j2se/1.4.2/download.html>here</a> "); document.write("to download and install JRE 1.4.2 and try to run the app again."); } </SCRIPT> </BODY> </HTML> |
一些JWS 应用程序可能希望访问客户端个人计算机上的服务,比如用于读取和写入文件或打开套接字并进行连接的 IO。为了安全性的目的,您不想恶意程序无限制地访问您的个人计算机上的这些工具,为此,JWS使用 Java 安全性模型和 JAR 文件认证。在缺省情况下,JWS虚拟机是一个受限的沙箱(Sandbox),它拒绝对这些服务的访问。如果您试图超出安全性管理器的许可,比如执行一些文件IO ,就会产生一个异常。
为了能够使用受限的 Java服务,您必须要求客户端授予访问权限。这可以通过 jnlp 文件中的 <security>标记来完成。下面的示例展示了请求 [2]<all-permissions/>的 HelloWorld.jnlp 文件中的 <security> 标记 [1]。
<?xml version="1.0" encoding="utf-8"?> <jnlp spec="1.0+" codebase="http://9.20.217.27:9080" href="HelloWorld.jnlp"> <information> <title>HelloWorld</title> <vendor>IBM - JWS example of HelloWorld</vendor> <description>HelloWorld - Example of JWS</description> <description kind="short">HelloWorld example</description> <offline-allowed/> </information> [1] <security> [2] <all-permissions/> </security> <resources> <j2se version="1.3+"/> <jar href="HelloWorld.jar"/> </resources> <application-desc main-class="HelloWorld"/> </jnlp> |
为了应用安全性必须签署 JAR文件。不能签署的 JAR 文件将导致如下所示的安全性错误。
为了签署 JAR 文件,您可以使用 JDK 附带的 keytool命令,即使您将把您的 JWS应用程序放在完整的产品中,也还是推荐您从像 Thawte或 VeriSign这样的结构获得认证。
为了测试的目的,我们将使用 keytool来创建一个公共和私有密钥对,并且通过 wsddjws 的密钥和richjavaclient 的密码来签署 HelloWorld.jar。新生成的认证将放入名为 joestore(具有别名 helloAlias)的keystore 中。这通过以下命令来完成:
keytool -genkey -alias helloAlias -keypass wsddjws -keystore joestore -storepass richjavaclient |
keytool命令将提示输入信息,比如您的姓名、公司及地址。这是以便于询问用户授权JAR许可来访问他们的系统,可以做出关于是否相信程序源的决定。这样,被要求授予访问其系统的JAR 许可的用户就可以决定他们是否信任该程序。
在创建了密钥之后,我们将使用 jarsigner命令来创建已签署的 jar,将其命名为 sHelloWorld.jar。从 WebSphere Studio导出的HelloWorld.jar 的位置是 C:\temp,已签署的 jar将被放回到相同的文件夹中。
jarsigner -keystore joestore -signedjar C:\temp\sHelloWorld.jar C:\temp\HelloWorld.jar helloAlias |
可以通过用于认证的helloAlias 的别名来签署 jar,并且系统将提示您输入认证的密码短语(Passphrase)和密码。
在这完成之后,文件C:\temp\sHelloWorld.jar 就可以导入 WebSphere Studio Web 项目,然后更新HelloWorld.jnlp 文件来应用它。当 jnlp文件下载完时,客户端将提示是否授权 HelloWorld访问用户的系统。
在提供了认证授权之后,JWS就不再需要把状态消息“Java Application Window”放在 GUI的底部,而它会作为任何其他本地运行的客户端出现。
一旦认证由用户进行了授权,它就可以重用,因此如果您想要配置另一个JWS 应用程序,您可以在 joestore 中重用 helloAlias 认证来签署更多的 JAR文件,系统将不会再一个一个地重新提示用户。关于 Java安全性的更多信息请参见 Sun 上的 Java 2 SDK 1.2中的性安全性教程。
在上述步骤中,我们必须执行两个步骤,这两个步骤可以通过简单的Servlet 进行简化。在 jnlp 文件中包括代码库的显式 URL,此外还必须更改 WebSphere测试环境的 mime 类型关联。
第一步是获得 jnlp-servlet.jar文件并且将其添加到 Web 项目中的 WEB-INF/lib文件夹。该文件在 JNLP 开发包中,您可以 从Sun 下载。
在这完成之后,就应该更新 WEB-INF文件夹中的 web.xml 文件了。XML tags for <servlet>、<servlet-mapping>和 <mime-mapping> 的XML 标记应该插到 <web-app> 标记中。如果这些标记在 XML文件中的位置不正确,那么 web.xml文件的 WebSphere Studio 确认将报告错误,并且它们应该放在 <welcome-file-list>标记之前。
<servlet> 标记 [1] 告知 WebSphere Studio如何调用 Servlet 类 com.sun.javaws.servlet.JnlpDownloadServlet,它是jnlp-servlet.jar的一部分。<servlet-mapping> 标记 [2] 告知容器何时调用 Servlet,我们希望它为带有后缀 .jnlp的文件运行。最后,< mime-mapping> 标记 [3] 允许您指定应用程序 MIME 类型与 jnlp文件相关联而不必改变 WebSphere本身的配置。这允许您更容易地创建打包的 EAR,EAR可以部署到现有的服务器中,该服务器包含在其中运行 EAR所需的全部信息,并且不需要服务器管理器更新它的配置。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app id="WebApp"> <display-name>JavaWebStartTest</display-name> [1] <servlet> <servlet-name>JnlpDownloadServlet</servlet-name> <display-name>JnlpDownloadServlet</display-name> <servlet-class>com.sun.javaws.servlet.JnlpDownloadServlet</servlet-class> <load-on-startup>-1</load-on-startup> </servlet> [2] <servlet-mapping> <servlet-name>JnlpDownloadServlet</servlet-name> <url-pattern>*.jnlp</url-pattern> </servlet-mapping> [3] <mime-mapping> <extension>jnlp</extension> <mime-type>application/x-java-jnlp-file</mime-type> </mime-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app> |
已经在 /lib 目录中包括了 jnlp-server.jar并且更新了 web.xml 文件来指定 mime 类型和 JnlpDownloadServer,这意味着 .jnlp文件本身可以简化。在前面创建 HelloWorld.jnlp 时,这会在它的 jnlp标记中硬编码 Web 服务器的显式 URL。然而,JnlpDownloadServlet所做的是在所有带有 .jnlp扩展名的文件上运行并且允许替换此信息,这样短语 $$codebase就可以软编码成 .jnlp 文件[1],并且这将会变成代码库,而无论在哪里请求 .jnlp文件都是如此。
<?xml spec="1.0+" version="1.0" encoding="utf-8"?> <jnlp [1] codebase=$$codebase> ... remainder of jnlp file </jnlp> |
同样, 因为 <mime-mapping>标签已经设置在 web.xml中,所以可以删除 .jnlp 文件后缀与服务器配置的 Web标记中的应用程序的显式关联。
客户端个人计算机缓存应用程序JAR 文件以及原始的 jnlp文件的日期和时间戳。这些信息存放于在 Application Manager 的Advanced 选项卡中指定的文件夹内。
当通过JWS 启动应用程序时,它首先检查缓存,查看它是否从相同的 URL访问过具有指定的名称的 jnlp 文件。如果是这样的,它然后就根据缓存中存储的日期和时间戳来检查服务器中的 jnlp文件的日期和时间戳。如果匹配,就意味着本地版本不是旧的,JWS将用这个版本来启动应用程序而不用重新下载 JAR文件。如果日期和时间戳不匹配,那么 JWS 将从 jnlp文件中指定的位置下载最新的版本,重新缓存它,并继续启动程序。在JWS非常缓慢地从它所需的服务器下载新的软件版本的情况下,这种方法允许您在一个地方集中地管理更改并且确保客户端将自动地更新。
在将 jnlp文件的日期和时间戳用作触发器来使客户端重新下载版本的情况下,这种存在这样的一个问题,为了加载平衡相同的jnlp文件可能会复制到几个服务器中。在这种情况下,客户端将检测该文件是否已经发生改变,并且在缓存的版本需要时下载新的程序版本。为了避免出现这个问题,可以将时间戳显式包括在jnlp 文件中,方式是启动带有 TS: 的第一行,TS: 之后是 ISO8601 日期和时间戳。例如,如果您想让您的文件的时间戳为 8月 13 日下午 3点 30 秒,[1] 行将插入起始 <?xml 标记之前。
JnlpDownloadServlet 负责识别以 TS 打头的代码行并且在返回到客户端的响应中替换日期和时间戳,因此必须为Web 项目采取 改进部署和配置部分中所述的步骤。
[1]TS: 2003-08-13 15:00:30 <?xml version="1.0" encoding="utf-8"?> <jnlp spec="1.0+" codebase="$$codebase" href="HelloWorld.jnlp"> <information> <title>HelloWorld</title> <vendor>IBM - JWS example of HelloWorld</vendor> <description>HelloWorld - Example of JWS</description> <description kind="short">HelloWorld example</description> <offline-allowed/> </information> <resources> <j2se version="1.3+"/> <jar href="HelloWorld.jar"/> </resources> <application-desc main-class="HelloWorld"/> </jnlp> |
TS:包括的线,jnlp file可在服务器和客户端的 JWS之间移动,这将总是拾取编码日期和时间印章作为应用程序的签名。这意味着作为应用程序的提供者,当您希望配置新的程序版本时,您负责改变时间印章和日期,但是在客户端未错误检查文件已改变的条件下,在服务器间移动文件是有利的。
对于所包括的TS: 行,jnlp 文件可以在服务器和客户端上的 JWS之间移动,并且将一直挑选已编码的日期和时间戳作为应用程序的签名。现在这意味着,作为应用程序的提供者,您负责显式地更改日期和时间戳(当您希望部署新的程序版本时),但是如果并未错误地检测到文件已经发生改变,那么在服务器之间移动文件是有利的。