`
bsr1983
  • 浏览: 1100825 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

第十章 部署applet和应用程序

阅读更多
10.1 applet基础
10.1.1 一个简单的applet
注意:如果applet包含Swing组件,则必须继承JApplet类。Applet类中的Swing组件不能正确地显示出来。
10.1.2 查看applet
要执行applet,需要执行下面两个步骤:
1)编译Java源文件,生成类文件。
2)创建HTML文件,告诉浏览器首先加载哪个类文件以及如何设定applet的大小。
提示:有一个技巧可以用来避免创建另外的HTML文件,即在源文件中直接添加applet标记作为注释:
/*
<applet code="MyApplet.class" width="300" height="300">
</applet>
   */
public class MyApplet extends JApplet
......
然后把源文件作为命令行参数运行applet查看器:
appletviewer MyApplet.java(注意这里是源文件而不是class文件)
提示:如果改变了applet并重新编译,则应该重新期铜浏览器来加载新的类文件。只刷新HTML页面是不会加载新代码的。这使得调试applet非常麻烦。通过启动Java控制台并使用命令X来清理类加载器cache,可以避免多次重新启动浏览器。然后可以重新加载HTML页面,使用新的applet代码。在Netscape和Mozilla中可以通过菜单启动Java控制台。在Windows下,通过控制面板中的Java Plug-in控制台来提出显示Java控制台的申请。
10.1.3 将应用程序转换为applet
10.1.4 applet的生命周期
Applet类提供了四种方法,这位构造重要的applet提供了框架,这几个重要的applet包括init、start、stop和destory。
1)init
当初始化applet时,需要调用该方法。在处理完applet标记中的param标记之后调用该方法。applet中常用的动作有对param参数进行处理以及增加用户界面组件。
2)start
该方法会在浏览器调用init方法之后自动地执行。当用户从其他页面返回到包含applet的页面时,也会调用该方法。这就意味着可能会多次调用start方法,而init只能调用一次,由于这个原因,因此可以把希望只执行一次的代码放置在init方法中,而不是放在start方法中。start方法经常为applet程序启动一个线程,例如,恢复动画。如果applet在用户离开当前页面时没有什么需要挂起的,没有必要实现该方法(或者stop方法)。
3)stop
该方法在用户离开包含applet的页面时会被自动地调用。它也可以在一个applet中被多次调用。目的在于当用户不在关注这个applet时,有机会停止那些降低系统运行的耗时操作。需要实现该方法来停止动画或音频的播放。
4)destory
该方法只有在浏览器正常关闭时才会被调用。因为applet只生存在HTML页面中,因此当用户不在浏览包含applet的网页时,applet不应该再在系统中占用资源。如果想达到这一目的,可以通过覆盖destroy方法来关闭这些资源。
10.1.5 安全基础
applet安全管理器(security manager)在applet违反任何访问规则时都会抛出一个SecurityException。
通过使用签名applet(signed applet),就可以针对不同的情况给予不同的安全等级。签名的applet携带一个可以证明签名者身份的证书。加密技术可以保证这种证书是不可伪造的。如果信任签名者,就可以给予applet额外的权限。
注意:Java Web Start 应用程序具有一个功能更强的沙箱。如果用户允许,一些系统资源是可以被访问的。
总之,Java通过三个独立的机制来加强安全性:
1)程序代码被Java虚拟机解释,而不是直接执行。
2)安全管理器检查所有Java运行库中敏感的操作。
3)applet可以通过签名技术来证实其来源。
10.1.6 applet中的弹出式窗口
10.2 applet的HTML标记和属性
10.2.1 用于定位的applet属性
下面讨论可以(或者必须)在applet标记中使用的用于定位applet的各种属性。
1)width,height
这些属性是必需的,它以像素为单位设定applet的宽度和高度。
2)align
这个属性指定applet的对齐方式。
10.2.2 用于编码的applet属性
1)code
这个属性给出applet类文件的名称。这个名称不是相对于代码库(codebase)的,就是在没有指定codebase的时候,相对于当前页面的。如果类文件存放在其他地方,那么应该使用codebase属性。
code属性仅仅用于指定包含applet类的类名。
code和object属性都是必需的。
2)codebase
这个可选属性指出用于定位类文件的URL。可以使用绝对URL,甚至是不同的服务器。最常见的情况是,使用指向子目录的相对URL。
3)archive
这个可选属性列出Java存档文件、包含类文件及applet需要的其他资源的文件。这些文件是在applet被加载前从Web服务器端取得的。
4)object
这个标记用来指定包含序列化(serialized)的applet对象文件的名字。(当把所有的实例域都写到一个文件中时,对象被序列化。)
5)name
页面脚本编写人员希望为applet赋予name属性,这样在编写脚本时,可以使用这个属性来代表相应的applet。
要从JavaScript中访问applet,首先需要为其指定一个名字:
<applet code="CaleulatorApplet.class" width="100" height="150" name="calc">
</applet>
使用document.applets.appletname来引用该对象。例如:
var calcApplet=document.applets.calc;
通过使用Netscape和Internet Explorer提供的将Java和JavaScript集成的能力,可以调用applet方法:
calcApplet.clear();
要使同一个页面上的两个applet之间可以直接通信,必须为每个applet指定name属性。
10.2.3 不支持Java兼容浏览器的applet属性
如果一个不支持Java applet的浏览器包含applet标记的网页,则该浏览器会忽略不认识的applet标记和param标记。<applet>和</applet>标记之间的文本都会由浏览器显示出来。相反,支持Java的浏览器不显示<applet>和</applet>标记之间的文本。
10.2.4 object标记
object标记是HTML4.0标准中的一部分,而W3歇会建议使用它来代替applet标记。object标记有35个不同的属性,大部分的属性只适用于编写动态HTML的用户。
对于Java applet而言,object标记中的关键属性石classid。这个属性指定对象的位置。在codetype属性中,可以指定对象的性质。例如,Java applet的代码类型是application/java。下面是加载Java applet的object标记的例子:
<object codetype="application/java"
      classid="java:CalulatorApplet.class"
      width="100" height="150">
注意,classid属性后面可以跟codebase属性,其用法与在applet标记中一样。
10.2.5 使用参数向applet传递信息
注意:只能在applet中的init方法中调用getParameter方法,而不是在构造器重调用。当applet构造器执行时,参数还没有准备好。因为许多重要的applet的布局都是由参数决定的,建议读者不要给applet提供构造器,而是将所有初始化代码都放到init方法中。
注意:在param标记中定义的参数字符串应与getParameter方法中使用的字符串完全匹配。尤其是,两者都区分大小写。
10.3 多媒体
applet可以处理图像和音频。
10.3.1 封装URL
URL只是对Internet上一个资源的描述。
10.3.2 获取多媒体文件
可以通过getImage和getAudioClip方法获取图像和音频文件。
10.4 applet上下文
applet调用getAppletContext方法来与浏览器通信。这个方法返回一个实现了AppletContext类型的接口对象。可以认为AppletContext接口的具体实现就是applet与环境浏览器之间的通信路径。
10.4.1 applet间的通信
一个网页可以包含多个applet。如果网页中包含的多个applet都来自于同一个codebase,那么他们直接可以相互通信。
如果为HTML文件中的每个applet都制定name属性,就可以使用AppletContext接口中的getApplet方法来获得对applet的引用。
10.4.2 在浏览器中显示信息
通过AppletContext类可访问环境浏览器的两个区域:状态行和网页显示区域。
表10-2 showDocument方法
目标参数 位置
"_self"或者none 在当前框架中显示文档
"_parent" 在父框架中显示文档
"_top" 在最顶层框架中显示文档
"_blank" 打开新的、未命名的、最顶层的窗口
任何其他字符串 在具有指定名称的框架中显示文档。如果没有具有该名字的框架,则打开新窗口并给该窗口指定名称

10.4.3 书签applet
10.4.4 既是applet,又是应用程序
10.5 JAR文件
构建JAR文件最常用的命令使用如下语法:
jar cvf JARFileName File1 File2...
选项 说明
c    建立一个新的或者空的存档文件并加入文件。如果指定的文件名是目录,jar程序会对它们进行递归处理
t    显示内容表
u    更新一个已有的JAR文件
x    解压缩文件。如果提供一个或多个文件名,那么直接压这些文件。否则,解压所有文件
f    把JAR文件名指定为第二个命令行参数。如果没有这个参数,jar命令会将结果写到标准输出上(在创建JAR文件时)或者从标准输入中读取它(在解压或者列出JAR文件内容时)
v    创建详细的输出结果
m    在JAR文件中加入清单文件(manifest)。清单是对存档内容的来源的说明。每个归档文件都有一个默认的清单文件。但是如果想验证归档文件的内容,可以自己提供自己的清单文件
0    只存储,不经过ZIP压缩
M    不为特定的条目创建清单文件
i    建立索引文件
C    暂时改变目录,例如:
   jar cvf JARFileName.jar -C classes *.class
   会改变到classes子目录来增加这些类条件
提示:如果applet很大,而且不是所有用户都需要所有功能时,为了减少下载时间,可以把applet代码分解为多个JAR文件,并且在主JAR文件中增加一个索引(index)类加载器知道在哪个JAR文件中包含特定的包或资源。
10.6 应用程序打包
10.6.1 清单文件
JAR文件是一个简单的ZIP文件,它包含类文件、程序需要的其他文件(如图标)以及描述存档特性的清单文件(mainfest)。
清单文件被命名为MANIFEST.MF,它在JAR文件的一个特殊的META-INF子目录下面。
10.6.2 自运行JAR文件
要想打包一个应用程序,就应该将应用程序需要的所有文件放置到一个JAR文件中,然后在清单文件中增加一项来指定程序的主类(main class)——该类一般需要调用java程序启动器指定的类。
创建一个名为mainclass.mf的文件,其中包含下面一行:
Main-Class:com/mycompany/mypkg/MainAppClass
10.6.3 资源
提示:本章前面讲过,applet可以使用getImage和getAudioClip方法类定位图像和音频文件,这些方法将自动地寻找JAR文件。但是,加载JAR文件中的其他类型文件,applet需要使用getResourceAsStream方法。
一个以“/”开头的资源名称为绝对资源名称。它的定位方式和类在包中的定位方式一样。
10.6.4 密封
在第4章提到过,可以将Java语言包密封(seal),以保证其他类不能再加入到其中。如果在代码中使用包可见的类、方法和域,那么可能希望对包密封。如果不密封,其他类就可以放置在这个包中,因此它们就可以访问包可见的特性。
在默认情况下,JAR文件中的包是没有密封的。可以在清单文件的主节中加入下面一行:
Selaled:true;
来改变全局默认的设定。对于每个单独的包,通过在JAR文件清单中增加一节,可以指定是否密封该包。
要密封一个包,应创建一个包含清单文件指令的文本文件。然后使用通常的方式运行jar命令:
jar cvfm MyArchive.jar manifest.mf file to add
10.7 Java Web Start               2010-10-11        489页
Java Web Start应用程序和applet之间的区别:
1)Java Web Start用于发布普通的Java应用程序,这些应用程序将通过调用类中的main方法开始运行,并且不需要继承Applet类。
2)Java Web Start应用程序不存在与浏览器中,它是在浏览器之外显示的。
3)Java Web Start应用程序可以通过浏览器启动,但是底层机制与启动applet有很大区别。浏览器和执行applet的Java运行环境紧密结合。而Java Web Start的集成就更为松散。当加载一个Java Web Start应用程序描述符时,浏览器只启动一个外部应用程序。这一点和浏览器启动如Adobe Acrobat或RealAudio这样的辅助应用程序的机制一样。即使是不友好的浏览器提供商也不会干扰这种机制。
4)一旦下载一个Java Web Start应用程序,它就可以在浏览器之外启动。
5)Java Web Start的“沙箱”比较宽松,它允许未签名的应用程序访问一些本地资源。
为了准备一个通过Java Web Start发布的应用程序,应该将其打包到一个或多个JAR文件中。然后创建一个Java Network Launch Protocol(JNLP)格式的描述符文件。把这些文件放置在Web服务器上。下一步,要确保Web服务器对于具有.jnlp后缀的文件报告一个application/x-java-jnlp-file的MIME类型描述。
JNLP API
为了使Java Web Start应用程序具有访问本地机器全部资源的权限,应用程序必须有数字签名。
API提供下列服务:
1)加载和保存文件
2)访问剪贴板
3)下载文件
4)打印
5)保存和获取持久性的配置信息
6)在默认的浏览器中显示一个文档
7)保证只运行一个应用程序的实例(JDK5.0中新增)
要访问服务,需要使用ServiceManager,如下所示:
FileSaveService service=(FileSaveService)ServiceManager.lookup("javax.jnlp.FileSavaService");
如果服务不可用,调用将抛出UnavailableServiceException。
注意:要编译使用了JNLP API的程序,必须在类路径中包含javaws.jar文件,这个文件在JDK的jre/lib子目录下。
注意:从JDK5.0开始,Java Web Start应用程序和applet都可以使用常用打印API来打印,会弹出安全对话框询问用户是否运行访问打印机。
10.8 应用程序配置的存储
10.8.1 属性映射
属性映射(property map)是存储键/值对的数据结构。属性映射经常用来存放配置信息。它有三个特性:
1)键和值都是字符串
2)该键/值对都可以很容易地写入文件或从文件读取
3)使用二级表来存放默认值。
Properties类有两种提供默认值的机制。第一种方法是在试图获取字符串的值时,可以指定默认值,当键值不存在时,就会自动使用它。
String font=setting.getProperty("font","Courier");
如果在属性表中有“font”属性,font会被设置成对应的值。否则,字体会设置成"Courier"。
如果认为每次调用getProperty方法是都要指定默认值太麻烦,可以把所有的默认值构造成一个二级属性映射,并且用它来构造查询表。
注意:Properties类扩展了Hashtable类。这就是说,所有Hashtable的方法可以被Properties对象使用。
10.8.2 系统信息
注意:可以在Java运行时目录中的security/java.policy文件里找到所有可以访问的系统属性名称。
10.8.3 Perferences API
JDK1.4中的Preferences类提供了一个与平台无关的中心知识库。在Windows中,Preferences类使用注册表来存储信息;在Linux中,这些信息存放在本地文件系统中。当然,对于使用Preferences类的程序员而言,中心知识库的实现是透明的。
中心知识库中的每个节点都有一个独立的表来存放键/值对。用户可以用它来存放数字、字符串或字节数组,但不适合存放序列化的对象。
为了得到更多的灵活性,系统中有多个并行的树。每个程序使用者有一棵树,同时,操作系统中还存在一棵树,称为系统树,用来存放全部用户共有的信息。Preferences类使用操作系统中“当前用户”概念来确保用户访问恰当的用户树。
为了访问树中节点,要从用户或系统的根开始:
Preferences root=Preferences.userRoot();

Preferences root=Preferences .systemRoot();
然后访问该节点。可以只提供节点的路径名:
Preferences node=root.node("/cod/mycompany/myapp");
如果节点的路径名和类的包名一样,则有一种简单、快捷的方法获取该节点。只需要获取该类的对象,然后调用:
Preferences node=Preferences.userNodeForPackage(obj.getClass());
或者
Preferences node=Preferences.systemNodeForPackage(obj.getClass());
Preferences类可以调用下面的方法将子树(或者一个节点)的配置信息导出
void exportSubtree(OutputStream out)
void exportNode(OutputStream out)
数据以XML格式存储。可以通过以下调用将其导入到另一个中心知识库:
void importPreferences(InputStream in)
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics