Java Web Start 指南

1. 概述

本文解释了 Java Web Start (JWS) 是什么,如何在服务器端配置它,以及如何创建一个简单的应用程序。

注意:从 Java 11 开始,JWS 已从 Oracle JDK 中删除。作为替代方案,请考虑使用OpenWebStart

2. 简介

JWS 是随 Java SE 一起提供的运行时环境,用于客户端的 Web 浏览器,自 Java 版本 5 以来一直存在。

通过从 Web 服务器下载 JNLP 文件(也称为 Java 网络启动协议),此环境允许我们远程运行其引用的 JAR 包。

简而言之,该机制通过常规 J​​RE 安装在客户端计算机上加载和运行 Java 类。它还允许来自 Jakarta EE 的一些额外指令。但是,客户端的 JRE 严格应用安全限制,通常警告用户不可信的域、缺少 HTTPS 甚至未签名的 JAR。

可以从通用网站下载 JNLP 文件以执行 JWS 应用程序。下载后,可以直接从桌面快捷方式或 Java Cache Viewer 运行。之后,它会下载并执行 JAR 文件。

这种机制对于提供非基于 Web(无 HTML)的图形界面非常有帮助,例如安全文件传输应用程序、科学计算器、安全键盘、本地图像浏览器等。

3. 一个简单的 JNLP 应用程序

一个好的方法是编写一个应用程序并将其打包到一个 WAR 文件中以供常规 Web 服务器使用。我们所需要的只是编写我们想要的应用程序(通常使用 Swing)并将其打包到 JAR 文件中。然后,这个 JAR 必须与 JNLP 一起打包到一个 WAR 文件中,该 JNLP 将正常引用、下载和执行其应用程序的Main类。

与打包在 WAR 文件中的常规 Web 应用程序没有区别,只是我们需要一个 JNLP 文件来启用 JWS,如下所示。

3.1。Java 应用程序

让我们从编写一个简单的 Java 应用程序开始:

public class Hello {
    public static void main(String[] args) {
        JFrame f = new JFrame("main");
        f.setSize(200, 100);
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JLabel label = new JLabel("Hello World");
        f.add(label);
        f.setVisible(true);
    }
}

我们可以看到这是一个非常简单的 Swing 类。实际上,没有添加任何内容来使其符合 JWS。

3.2. Web应用程序

我们所需要的只是将这个示例 Swing 类与以下 JNLP 文件一起 JAR 打包到一个 WAR 文件中:

<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" 
  codebase="http://localhost:8080/jnlp-example">
    <information>
        <title>Hello</title>
        <vendor>Example</vendor>
    </information>
    <resources>
        <j2se version="1.2+"/>
        <jar href="hello.jar" main="true" />
    </resources>
    <application-desc/>
</jnlp>

让我们将其命名为hello.jndl并将其放在 WAR 的任何 Web 文件夹下。JAR 和 WAR 都是可下载的,因此我们不必担心将 JAR 放在lib文件夹中。

我们最终 JAR 的 URL 地址被硬编码在 JNLP 文件中,这可能会导致一些分发问题。如果我们更改部署服务器,应用程序将不再工作。

让我们在本文后面使用适当的 servlet 来解决这个问题。现在,让我们将要下载的 JAR 文件作为index.html放在根文件夹中,并将其链接到锚元素:

<a href="hello.jnlp">Launch</a>

我们还要在 JAR Manifest 中设置主类。这可以通过在pom.xml文件中配置 JAR 插件来实现。同样,我们将 JAR 文件移到WEB-INF/lib之外,因为它仅供下载,即不适用于类加载器:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    ...
    <executions>
        <execution>
            <phase>compile</phase>
            <goals>
                <goal>jar</goal>
            </goals>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>
                            com.example.Hello
                        </mainClass>
                    </manifest>
                </archive>
                <outputDirectory>
                    ${project.basedir}/target/jws
                </outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

4. 特殊配置

4.1。安全问题

要运行应用程序,我们需要对 JAR 进行签名。创建有效证书并使用 JAR Sign Maven 插件超出了本文的范围,但我们可以绕过此安全策略用于开发目的,或者如果我们对用户计算机具有管理访问权限。

为此,我们需要将本地 URL(例如:http://localhost:8080)添加到将执行应用程序的计算机上的 JRE 安装的安全例外列表中。可以通过在安全选项卡上打开 Java 控制面板(在 Windows 上,我们可以通过控制面板找到它)来找到它。

5. JnlpDownloadServlet

5.1。压缩算法

有一个特殊的 servlet 可以包含在我们的 WAR 中。它通过查找我们的 JAR 文件的最压缩编译版本(如果可用)来优化下载,并且还修复了 JLNP 文件上的硬编码代码库值。

由于我们的 JAR 可供下载,因此建议使用压缩算法(如 Pack200)对其进行打包,并将常规 JAR 和任何 JAR.PACK.GZ 或 JAR.GZ 压缩版本放在同一文件夹中,以便此 servlet 可以为每种情况选择最佳选项。

不幸的是,目前还没有用于此压缩算法的 Maven 插件的稳定版本,但我们可以使用 JRE 附带的 Pack200 可执行文件(通常安装在路径{JAVA_SDK_HOME}/jre/bin/上)。

在不更改我们的 JNLP 并将 JAR 的jar.gzjar.pack.gz版本放在同一个文件夹中的情况下,当 servlet 收到来自远程 JNLP 的调用时,它会选择更好的版本。这增强了用户体验并优化了网络流量。

5.2. 代码库动态替换

servlet 还可以对<jnlp spec=”1.0+” codebase=”http://localhost:8080/jnlp-example”>标记中的硬编码 URL 执行动态替换。通过将 JNLP 更改为通配符<jnlp spec=”1.0+” codebase=”$$context”>,它提供了相同的最终渲染标签。

servlet 还可以使用通配符$$codebase$$hostname$$name$$site,它们将解析“ http://localhost:8080/jnlp-example/ ”、“ localhost:8080 ”、“ hello. jnlp ”和“ http://localhost:8080 ”。

5.3. 将 Servlet 添加到类路径

要添加 servlet,让我们为 JAR 和 JNLP 模式配置一个正常的 servlet 映射到我们的web.xml

<servlet>
    <servlet-name>JnlpDownloadServlet</servlet-name>
    <servlet-class>
        jnlp.sample.servlet.JnlpDownloadServlet
    </servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>JnlpDownloadServlet</servlet-name>
    <url-pattern>*.jar</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>JnlpDownloadServlet</servlet-name>
    <url-pattern>*.jnlp</url-pattern>
</servlet-mapping>

servlet 本身包含一组 JAR(jardiff.jarjnlp-servlet.jar),现在位于 Java SDK 下载页面的 Demos & Samples 部分。

在 GitHub 示例中,这些文件包含在java-core-samples-lib文件夹中,并由 Maven WAR 插件作为 Web 资源包含在内:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    ...
    <configuration>
        <webResources>
            <resource>
                <directory>
                    ${project.basedir}/java-core-samples-lib/
                </directory>
                <includes>
                    <include>**/*.jar</include>
                </includes>
                <targetPath>WEB-INF/lib</targetPath>
            </resource>
        </webResources>
    </configuration>
</plugin>

6. 最后的想法

Java Web Start 是一种可以在没有应用服务器的(内联网)环境中使用的工具。此外,对于需要操作本地用户文件的应用程序。

应用程序通过简单的下载协议交付给最终用户,没有任何额外的依赖项或配置,除了一些安全问题(HTTPS、签名的 JAR 等)。

Git 示例中,可以下载本文中描述的完整源代码。我们可以直接从 GitHub 将它下载到带有 Tomcat 和 Apache Maven 的操作系统。下载后,我们需要从源目录运行mvn install命令,将生成的jws.war文件从目标复制到 Tomcat 安装的webapps文件夹中。

之后,我们就可以像往常一样启动Tomcat了。

在默认的 Apache Tomcat 安装中,该示例将在 URL http://localhost:8080/jws/index.html中提供。

猜你喜欢

转载自blog.csdn.net/allway2/article/details/126178773