`

Java Web Start实践:动态生成JNLP

阅读更多

Java很早就推出了Java Web Start(简称JWS)技术。这一技术的初衷很好:希望将桌面程序和Web页面之间搭起一个无缝的桥梁。虽然Applet技术已经存在了十多年,但是它日趋老迈衰落,所以JWS也就应运而生了。

但是JWS并未顺利实现它的初衷。从Java的几次大改版都可以看到,JWS的bug多多,漏洞频频,Sun和Oracle不得不频繁的进行打补丁修复。可以看看Java 5和6每次大小版本升级变化中,有多少是和Java Web Start有关的。难怪很多人都这样感叹:“哥再也不用Java Web Start部署应用了!”其实也未必,随着Java的不断完善,我们只要了解更多的技巧,就可以有效的消除一些JWS潜在的问题,并顺利地应用在企业应用中。

以2BizBox ERP项目为例,本文介绍如何在企业应用中利用动态生成JNLP文件的技术来实现应用的快速部署。



大家知道,2BizBox ERP作为一个免费的高质量ERP软件,有成千上万的用户。就我们开发团队负责维护的服务器,就有近千台。每台服务器都是一家企业,每家企业又有几十上百的客户端。如果采用下载客户端安装程序进行安装的方式来维护诸多的客户端,无疑是巨大的工作量,用户和我们开发团队都不会轻松方便。为了解决这一问题,采用JWS无疑是必然的选择。

为了让客户端自动启动下载和安装程序,我们在企业的2BizBox ERP服务器上部署以下JNLP文件内容:

 

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="http://**.**.**.**/webstart/">
        <information>
                <title>2BizBox</title>
                <vendor>Serva Software</vendor>
                <homepage href="http://www.2bizbox.com"/>
                <description>2BizBox ERP 3</description>
                <offline-allowed/>
        </information>
        <security>
                <all-permissions/>
        </security>
        <update check="always" policy="always"/>
        <resources>
                <j2se href="http://java.sun.com/products/autodl/j2se" version="1.6+" initial-heap-size="128m" max-heap-size="512m"/>
                <jar href="2bizbox.jar />
                <jar href="lib1.jar />
                <jar href="lib2.jar />
                <jar href="lib3.jar />
                <jar href="lib4.jar />
                <!-- more jar....   -->
        </resources>
        <application-desc main-class="com.serva.bb2.gui.Main">
                <argument>**.**.**.**</argument>
        </application-desc>
</jnlp>

 

上面的JNLP文件定义了2BizBox ERP客户端启动所需要的jar包以及下载位置、jre版本等。

在实际应用中,效果良好。但是由于JNLP和JWS本身的bug,在某些情况下,后台jar程序更新升级后,用户侧启动jnlp并不能获得更新,需要强行清空JWS缓存才行,这肯定不是一般用户懂得的。还有一种情况,就是由于ERP本身的jar包发生了变化(例如发生了增减),此时相当于jnlp文件的内容发生了变化。这时候,要求用户一侧机器必须意识到jnlp的变化并先将jnlp进行更新。在很多java版本中(例如jre6的早期版本——例如jre6 update20之前),由于潜在的一些bug等原因,都不能顺利地进行更新,导致程序启动失败。

如何解决这一情况呢?采用动态jnlp是一个有效的方法。

动态jnlp的思路是:在服务器的后端,通过jsp或servlet来动态的生成一个jnlp文件,而不是放置一个静态的固定不变的jnlp文件。这样,jnlp文件内容就可以通过后台应用的逻辑进行动态生成创建:需要什么jar包、需要什么jre版本等等。

以jsp为例。在这个jsp中,首先要注意的几个技术点是:要设置本页面不要被浏览器缓存,放置jnlp内容变化无法及时被更新;其次要设置mime类型让浏览器认为它是一个jnlp文件,以便下载执行而不是直接在浏览器中显示出来。通过设置response即可达到这些目的:

 

response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
response.setHeader("Content-Disposition", "filename=\"bb.jnlp\";");
response.setContentType("application/x-java-jnlp-file");

 

其中,禁止浏览器和webstart缓存jnlp内容,通过设置:response.setHeader("Pragma", "no-cache");和response.setHeader("Expires", "0"); 

设置文件类型,并给定一个动态的文件名。这个通过这个进行:response.setHeader("Content-Disposition", "filename=\"bb.jnlp\";");response.setContentType("application/x-java-jnlp-file");

一个需要注意的问题是,在动态生成jnlp文件时,要注意jnlp文件中的href标签不要进行设置。为什么呢?看一下jnlp的格式文档是这样说的:
http://lopica.sourceforge.net/ref.html#jnlp


The jnlp file's one and only root.

Attributes
spec=version , optional
Specifies what versions of the jnlp spec a jnlp file works with. The default value is 1.0+. Thus, you can typically leave it out.
version=version , optional
Specifies the version of the application as well as the version of the jnlp file itself.
codebase=url , optional
Specifies the codebase for the application. Codebase is also used as base URL for all relative URLs in href attributes.
href=url , optional
Contains the location of the jnlp file as a URL. If you leave out the href attribute, Web Start will disable the update check on your JNLP file, and Web Start will not treat each new JNLP file as an application update - only updated jar files will. Leaving out href usually makes only sense if your jnlp file is created dynamically (that is, throug a cgi-script, for example) and if your jnlp file's arguments or properties change from request to request (user to user).
Note, that Java Web Start needs href to list your app in the Web Start Application Manager.

可见在动态生成jnlp时候就不要设置href了,这样就可以保证每次浏览器会重新下载jnlp文件内容,否则可能会被缓存,无法及时更新程序。

另外一个技巧是:jnlp文件中的jar包,可以进行动态检查文件jar包并动态生成。这样,如果以后程序的jar文件有增减,就不必修改jnlp文件了。方法也很简单:检查当前web在服务器的绝对路径,并list所有的jar文件,然后在jnlp生成时候输出即可:

 

<%
String urlString=request.getRequestURL().toString();
URL url=new URL(urlString);
String host=url.getHost();
String path = request.getSession().getServletContext().getRealPath("/");
path=path.replace("\\.\\", "\\");
File file=new File(path);
String[] files = file.list();
ArrayList jarNames=new ArrayList();
for(int i=0;i<files.length;i++){
String fileName=files[i];
if(fileName.toLowerCase().endsWith(".jar")){
jarNames.add(fileName);
}
}
%>

 

然后在jar的部分这样列出:

 

 

        <resources>
                <j2se href="http://java.sun.com/products/autodl/j2se" version="1.6+" initial-heap-size="128m" max-heap-size="512m"/>
<%
for(int i=0;i<jarNames.size();i++){
out.write("\n");
out.write("<jar href=\""+jarNames.get(i).toString()+"\"/>");
}
%>
        </resources>

 

最后,如果需要在jnlp中指定当前服务器的ip地址或主机地址,也可以通过动态生成。例如jnlp文件中的codebase,就是如此。另外,2BizBox ERP还需要在主函数中给出当前服务器的ip地址。而对于上千家的2BizBox服务器,每个jnlp要手工维护ip地址,是不可想象的。这里通过动态生成,就永远的解决了这个问题:

 

String urlString=request.getRequestURL().toString();
URL url=new URL(urlString);
String host=url.getHost();

 

然后在jnlp中:

 

<jnlp spec="1.0+" codebase="http://<%=host%>/webstart/">
...
        <application-desc main-class="com.serva.bb2.gui.Main">
                <argument><%=host%></argument>
        </application-desc>

 

这样,通过jsp动态生成jnlp的方案就完成了。它在2BizBox ERP中应用良好,方便的让上千家2BizBox ERP的云主机用户快速得到程序更新,而简化了程序的维护方式。

 

分享到:
评论

相关推荐

    基于STM32单片机的激光雕刻机控制系统设计-含详细步骤和代码

    内容概要:本文详细介绍了基于STM32单片机的激光雕刻机控制系统的设计。系统包括硬件设计、软件设计和机械结构设计,主要功能有可调节激光功率大小、改变雕刻速率、手动定位、精确雕刻及切割。硬件部分包括STM32最小系统、步进电机驱动模块、激光发生器控制电路、人机交互电路和串口通信电路。软件部分涉及STM32CubeMX配置、G代码解析、步进电机控制、激光功率调节和手动定位功能的实现。 适合人群:对嵌入式系统和激光雕刻机感兴趣的工程师和技术人员。 使用场景及目标:① 适用于需要高精度激光雕刻的应用场合;② 为开发类似的激光雕刻控制系统提供设计参考。 阅读建议:本文提供了详细的硬件和软件设计方案,读者应结合实际应用场景进行理解,重点关注电路设计和代码实现。

    白色简洁风格的前端网站模板下载.zip

    白色简洁风格的前端网站模板下载.zip

    HarmonyException如何解决.md

    HarmonyException如何解决.md

    sdfsdfdsfsdfs222

    sdfsdfdsfsdfs222

    (177373454)html+css+js学习代码.zip

    html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+j

    usbgps2.apk

    usbgps2.apk

    白色简洁风格的家居建材网站模板下载.zip

    白色简洁风格的家居建材网站模板下载.zip

    EventEmitError解决办法.md

    EventEmitError解决办法.md

    白色简洁风格的工艺品展览企业网站源码下载.zip

    白色简洁风格的工艺品展览企业网站源码下载.zip

    matlab调制解调 OFDM OTFS 16qam qpsk ldpc turbo在高斯白噪声,频率选择性衰落信道下的误比特率性能仿真,matlab代码 OFDM simulink 包括添加保

    matlab调制解调 OFDM OTFS 16qam qpsk ldpc turbo在高斯白噪声,频率选择性衰落信道下的误比特率性能仿真,matlab代码 OFDM simulink 包括添加保护间隔(cp),信道均衡(ZF MMSE MRC MA LMSEE) 代码每行都有注释,适用于学习,附带仿真说明,完全不用担心看不懂

    build(1).gradle

    build(1).gradle

    贴标飞达sw16全套技术资料100%好用.zip

    贴标飞达sw16全套技术资料100%好用.zip

    其实这就是历年摘出来的

    其实这就是历年摘出来的

    地理遥感图像区域合并分割的大规模高效算法研究

    内容概要:本文针对大规模高分辨率遥感图像的处理问题,提出了一种基于图像分块的可扩展区域合并分割框架。传统的图像分块方法会导致分块边界上的伪影,影响最终结果。为解决这一问题,文中定义了稳定性边缘的概念,并给出了其数学表达,以确保分割结果与不分块时相同。此外,文章还介绍了一种高效的框架实现方法,用于在资源受限的设备上处理大型图像。 适合人群:从事遥感图像处理、计算机视觉及地理信息系统相关领域的研究人员和技术人员。 使用场景及目标:适用于需要处理大规模高分辨率遥感图像的应用场景,如环境监测、自然资源管理等。主要目标是提供一种能够高效处理大规模图像同时保持分割质量的方法。 其他说明:实验结果表明,所提出的算法不仅能够避免分块边界的伪影,而且能够在不同尺度下获得与不分块处理相同的分割结果。

    白色简洁风格的手机图片展示博客网站模板.rar

    白色简洁风格的手机图片展示博客网站模板.rar

    白色简洁风格的外科医疗整站网站源码下载.zip

    白色简洁风格的外科医疗整站网站源码下载.zip

    基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)

    基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计),本资源中的源码都是经过本地编译过可运行的,评审分达到98分,资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、毕业设计、期末大作业和课程设计使用需求,如果有需要的话可以放心下载使用。 基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医

    在线式缠绕膜机自动覆膜缠绕机sw16全套技术资料100%好用.zip

    在线式缠绕膜机自动覆膜缠绕机sw16全套技术资料100%好用.zip

    .archivetemp阅读天数.py

    .archivetemp阅读天数.py

Global site tag (gtag.js) - Google Analytics