您的位置:首页技术文章
文章详情页

从Firefox访问Java Plug-in

【字号: 日期:2024-06-16 15:32:59浏览:2作者:猪猪
内容: 摘要这篇文章与Jeff Friesen前一篇关于Java Plug-in的文章'Plug into Java with Java Plug-in' (JavaWorld, 6月 1999)是一个系列的。它专注于Firefox Web浏览器的最近的Java Plug-in其中之一。在篇文章中,你能学会从Firefox怎样访问Java Plug-in。你也能学到一些关于Java Plug-in文件对象模块(DOM),applet状态持久化,和cookie。除此以外,你还可以学习applet,它在Firefox中的运行,这将加强你对这些内容的理解。但那仅仅是开始。难道你曾经不想去探求Firefox是怎样与Java Plug-in(在后台)交互的吗?继续读下去你就会找到答案的。版权声明:任何获得Matrix授权的网站,转载时请务必保留以下作者信息和链接作者:Jeff Friesen;leo173(作者的blog:http://blog.matrix.org.cn/page/leo173)原文:http://www.javaworld.com/javaworld/jw-06-2005/jw-0627-plugin.html译文:http://www.matrix.org.cn/resource/article/44/44251_Firefox+Java+Plug-in.html关键字:Firefox;Java;Plug-in 从我在JavaWorld 上写'Plug into Java with Java Plug-in' 开始,9年已经过去了。我的前一篇文章给Java Plug-in下了定义,讲到了怎样在Netscape Communicator 4.5 和 Internet Explorer 3.02 上怎样安装版本1.2,描述了与Java Plug-in相关的Windows注册表设置,了解了Java Plug-in的控制面版,考查了两个java主控台,讨论了HTML 的 和 标签,还发布了一个基于Swing的用于Demo的applet。自从我写了那篇文章后,java和Java Plug-in已经相继发布了许多个版本。看来那篇文章已显老态,所以我已经写好它的系列篇,它专注于针对Firefox Web浏览器的最近的Java Plug-in其中之一。这篇文章首先为你讲解从Firefox怎样访问Java Plug-in。然后讨论Java Plug-in文件对象模块(DOM), applet状态持久化 和cookie。比如在Firefox上运行的各种applet,当你在学习这些内容时,将会强化你已经掌握的知识。这篇文章通过探寻Firefox 和Java Plug-in之间的联系,再做归纳。因为对于Java Plug-in而言,在其他地方会比我在这里所讲的要详细得多,所以我建议可以学习Sun的Java Plug-in文档,你将会学到更多的技术。这篇文章的实验环境是Mozilla Firefox 1.0, J2SE 5.0, 和Windows 98 SE。即使你没有这些软件,我仍然建议你读完这篇文章。真诚地希望你能发现一些对你来说还是未知的有兴趣的东西。Java Plug-in 和FirefoxJava Plug-in象桥一样服务于浏览器和一个外部的 java运行环境(JRE)之间。Java Plug-in对于在Firefox 中运行的applet而言是相当重要的,因为浏览器不能自身为其提供一个JRE——其中包括一个JVM。因为这篇文章描述的applet会涉及到不同多个不同的Java Plug-in内容,还有就是这些applet都是在Firefox的环境中运行的,所以我们首先应该看一下如何从Firefox中访问Java Plug-in。对于初学者来说,你必须确认在你的平台上已经安装了J2SE 5.0 和 JRE。在我的windows平台上,我用jdk-1_5_0-windows-i586.exe安装文件把J2SE 和 JRE都安装好了。确定你已经安装了JRE,因为JRE包含了Java Plug-in。在安装好J2SE 5.0后,连接Firefox 到 Java Plug-in;首先从Firefox的工具菜单中选择Options,然后选择Web Features,最后点击Enable Java checkbox。一般情况下,标签 和 应该指向在Java Plug-in下运行的applet。这对Java Plug-in 5.0来说不是必要的,它能运行由简单的标签指定的applet。在安装时,你有机会屏蔽Internet Explorer 和 Mozilla (Firefox)/Netscape Web浏览器对applet的执行,如果它们遇到了标签,而转交给Java Plug-in处理。如果你放弃这个选项,迟些时候你可以通过Java Plug-in的控制面版来完成这个变化。比如,打开控制面版,选择标签Advanced。然后点击 Tag Support左边的“+,再选择Mozilla and Netscape选项。关闭这个面版后,当Firefox遇到标签时,它就会交给Java Plug-in执行。图1给出了这些必要的改变。 选择Mozilla and Netscape,所以当Firefox遇到标签时,它就会交给Java Plug-in执行提示 我发现在我的平台上选择Mozilla and Netscape不是必须的。我的Firefox Web浏览器不会去管那个复选框的设置,当遇见时,它就会让Java Plug-in来执行。Java Plug-in 5.0的文档谈到这是个奇怪的行为:“如果Mozilla 和 Netscape 7都被安装好了,负责管理对标签是否支持的Mozilla and Netscape选项没有被选中的情况下,标签中的内容照样可以在Sun VM上运行。这是与Netscape 7的自动扫描功能相关的一个bug。因为我已经安装过Netscape 6.2.3,所以我认为我找到了这个bug。如果在你的平台上遇到了这个问题,记住这点就行了。平台上能驻留多个JRE,当Firefox遇到标签时,到底哪一个JRE来实现Java Plug-in?可以从Java Plug-in控制面版上的Java标签上找到答案。在二选一的情况下,我用来进行版本测试的applet给出了答案,同时也证明了Firefox是连接了 Java Plug-in的。图2显示我当前使用的JRE版本是1.5.0。(版本1.5.0是J2SE 5.0的内部版本号)图2. 我已经配置好使用JRE 1.5.0的Java Plug-inListing 1给出了该applet的VersionDemo.java文件的源代码。这些代码在系统属性java.version 中设置了JRE 的版本。Listing 1. VersionDetect.java // VersionDetect.javaimport java.awt.*;public class VersionDetect extends java.applet.Applet{ public void paint (Graphics g) { int width = getSize ().width; int height = getSize ().height; g.setColor (Color.orange); g.fillRect (0, 0, width, height); String version = 'JRE ' + System.getProperty ('java.version'); FontMetrics fm = g.getFontMetrics (); g.setColor (Color.black); g.drawString (version, (width-fm.stringWidth (version))/2, height/2); }} 为了简洁,在这篇文章中我将不会给出运行这个或者其他applet的HTML。参见这篇文章中的source code 。提示 Firefox只支持Java Plug-in 1.3.0_01和更高版本。调用DOM根据WWW 联合会 (W3C)所说,文件对象模块(DOM)是一个API,它针对“有效的HTML和合式的XML文档。它定义了文档的逻辑结构,访问和操作文档的方法。 Java Plug-in提供了两种方法来调用DOM:类netscape.javascript.JSObject和Common DOM API。JSObject为Java applet 和Web 浏览器的JavaScript实现之间提供了接口,包含使用了DOM 的JavaScript 对象。这些对象的例子:Document, Link, 和 Window。我将不会深入JSObject,因为在我早期的文章'Talk with Me Java'中,我已经讨论了这个类。因此我专注于在一个applet中,通过Common DOM API来遍历DOM 。在J2SE 版本1.4中已经介绍过Common DOM API,它是一个类和接口的集合,通过这些接口可以让applet遍历DOM实例。因为一个浏览器通过帧和窗口能够显示多个文档,所以会有许多DOM实例以备遍历。一般一个applet就遍历它自己的DOM实例—这个与文档相联系的DOM实例指定了这个applet。访问DOM实例的起点就是静态方法getService(Object obj),该方法位于类com.sun.java.browser.dom.DOMService中。一般情况下,一个被唤醒applet的this指针会被作为一个参数传递给getService()。这个方法要么返回一个 DOMService对象(为这个applet和它的DOM实例之间提供接口),要么抛一个异常:com.sun.java.browser.dom.DOMUnsupportedException (the DOM service is not available to the object) 或者 com.sun.java.browser.dom.DOMAccessException (a security violation has resulted)。例子:DOMService service = DOMService.getService (this);。因为web浏览器提供了不同的DOM实现,所以访问一个DOM实例不是线程安全的,除非那个访问是发生在DOM access dispatch线程。为了确保线程安全性,DOMService提供了两个方法来保证访问只是发生在DOM access dispatch线程—invokeLater() 和 invokeAndWait()。两种方法都用实现了接口com.sun.java.browser.dom.DOMAction的对象作为参数,来提供方法run()。invokeLater()在DOM dispatch线程中异步执行run(),invokeAndWait()在DOM dispatch线程中同步执行run()。方法run()用实现了接口com.sun.java.browser.dom.DOMAccessor的对象作为其唯一参数,然后返回一个基本的Object引用。方法run()经常唤醒DOMAccessor的getDocument()方法,传递一个applet的指针做getDocument()的Object参数。作为回应,getDocument()会返回一个实现org.w3c.dom.Document接口的对象。那个对象中就包含了这个文档的信息。对于HTML文档而言,它会把Document向下转型为HTMLDocument(位于org.w3c.dom.html中),然后调用HTMLDocument的方法去获取这个文档的标题,域,applet集,和一些其他的。在调用属性方法后,run()返回一个包含文档信息(比如HTMLDocument的标题)的Object对象。那个Object随后又从invokeAndWait()和invokeLater()方法中返回。为了梳理上面讨论的内容,我写了一个从一个HTML文档中提取标题的applet,然后把标题显示给用户。下面就是它的代码。Listing 2. TitleExtract.java // TitleExtract.javaimport com.sun.java.browser.dom.*;import java.applet.Applet;import java.awt.*;import org.w3c.dom.html.*;public class TitleExtract extends Applet{ private String title = 'unknown'; public void init () { try { DOMService service = DOMService.getService (this); title = (String) service.invokeAndWait (new DOMAction () {public Object run (DOMAccessor accessor){ HTMLDocument doc = (HTMLDocument) accessor.getDocument (TitleExtract.this); return doc.getTitle ();} }); } catch (DOMUnsupportedException e) { System.out.println ('DOM not supported'); } catch (DOMAccessException e) { System.out.println ('DOM cannot be accessed'); } } public void paint (Graphics g) { int width = getSize ().width; int height = getSize ().height; g.setColor (Color.cyan); g.fillRect (0, 0, width, height); FontMetrics fm = g.getFontMetrics (); g.setColor (Color.black); g.drawString (title, (width-fm.stringWidth (title))/2, height/2); }} DOMAction的run()方法调用了HTMLDocument的getTitle()方法去获取HTML文档的标题。随后显示该标题。例如,当在TitleExtract.html(参见本文的source code)中遇到元素时,getTitle()返回“Extract the title。图3中显示了Firefox中的结果。图3。 显示一个文档的标题注意 当从标签 中调用TitleExtract时,Firefox要求mayscript属性需要被给出。否则,由于Firefox的DOM实现依赖于JSObject,Java Plug-in会抛出各种异常。Applet在Firefox session中的持久状态Java Plug-in 5.0的文档提到许多有趣的课题。其中之一就是applet的持久性API,它可以让一个applet保存其状态以备在后来的相同的web浏览器session中使用。State被保存在由Java Plug-in控制的一个内部持久性存储数据结构中;一个session是指某个web浏览器被打开运行开始到这个浏览器被关闭结束。在J2SE 1.4中介绍的applet持久性API ,由声明在接口java.applet.AppletContext中的三个方法构成:· void setStream(String key, InputStream stream) throws IOException 需要当前applet上下文的一个具体key和具体的stream作为参数。如果一个新的stream对应了当前的key,这个新stream将会取代那个旧的stream。如果新stream的size超出了内部size的限制,将会抛出一个异常IOException。· InputStream getStream(String key)返回与当前applet key相联系的InputStream。如果没有指向该key的stream就返回null。· Iterator getStreamKeys()返回一个迭代器,它包括了指向当前applet中stream的所有key。通过调用setStream()来保存状态。这个方法把一个key(它可以方便地标识一个输入流)和一个InputStream的引用存储到一个内部数据结构中去,比如一个HashMap。取出某状态可以通过相应的标识key调用getStream()。它会返回一个InputStream(如果这个key存在)以恢复到这个状态。因为Java Plug-in5.0文档没有提供例子来指出怎样使用applet持久性API,所以我准备了一个例子。它给出了一个消息传送applet的两个实例,其中的一个使用applet持久性API发送消息给另一个。图4中,用户在左边实例的 Message To Send文本框中输入一个消息,然后点击该实例的Send按扭。然后用户点击右边实例的Receive按扭,这个消息就会在该实例的Message Received文本框中显示。图4 .applet的持久性API使applet之间相互发送消息给对方。点击“最大化消息发送发生在下面代码的action listener中。Listing 3. MessageTransfer.java // MessageTransfer.javaimport java.applet.*;import java.awt.*;import java.awt.event.*;import java.io.*;import javax.swing.*;public class MessageTransfer extends JApplet implements ActionListener{ private TextField txtRecvMsg, txtSendMsg; public void init () { // Build the applet's GUI. setLayout (new GridLayout (3, 1)); JPanel pnl = new JPanel (); pnl.setLayout (new FlowLayout (FlowLayout.LEFT)); pnl.add (new JLabel ('Message to send:')); txtSendMsg = new TextField (20); pnl.add (txtSendMsg); getContentPane ().add (pnl); pnl = new JPanel (); pnl.setLayout (new FlowLayout (FlowLayout.LEFT)); pnl.add (new JLabel ('Message received:')); txtRecvMsg = new TextField (20); pnl.add (txtRecvMsg); getContentPane ().add (pnl); pnl = new JPanel (); pnl.setLayout (new FlowLayout (FlowLayout.LEFT)); JButton btnSend = new JButton ('Send'); btnSend.addActionListener (this); pnl.add (btnSend); JButton btnReceive = new JButton ('Receive'); btnReceive.addActionListener (this); pnl.add (btnReceive); getContentPane ().add (pnl); } public void actionPerformed (ActionEvent e) { JButton btn = (JButton) e.getSource (); if (btn.getText ().equals ('Send')) { String text = txtSendMsg.getText (); try { // Output the String object to a byte array output stream. ByteArrayOutputStream baos = new ByteArrayOutputStream (); ObjectOutputStream oos = new ObjectOutputStream (baos); oos.writeObject (text); oos.close (); // Extract the String object from the byte array output stream // as an array of bytes. byte [] data = baos.toByteArray (); // Convert the array of bytes to a byte array input stream. When // the setStream() method is invoked, it caches the input stream // reference and key in the applet persistent store. InputStream is = new ByteArrayInputStream (data); getAppletContext ().setStream ('text', is); } catch (Exception e2) { System.out.println (e2.toString ()); } } else { InputStream is = getAppletContext ().getStream ('text'); if (is != null) try { // Input the cached String object. ObjectInputStream ois = new ObjectInputStream (is); String text = (String) ois.readObject (); txtRecvMsg.setText (text); } catch (Exception e2) { System.out.println (e2.toString ()); } } }} 这个消息发送applet把消息持久化为一个string对象,通过把这个对象序列化到ByteArrayOutputStream,转化这个stream到一个byte数组,基于这个byte数组构建一个ByteArrayInputStream,然后通过这个stream和一个名为text的key调用方法setStream()。该applet用这个名为text的key调用getStream()取回这个消息,然后反序列化这个InputStream。在Firefox中,被持久化后的消息对在不同窗口或面版上运行的applet都是可以被访问的。这种消息对不同session(也就是说,Firefox的不同实例)中运行的applet是不能被访问的,因为每个session只与它自己的Java Plug-in实例和内部持久性存储数据结构进行通信。提示 出于安全考虑,使用不同codebase的applet不能访问对方的stream。了解cookieWeb浏览器和web服务器经常发送小的数据包给对方进行交互。这些包,也就是大家知道的cookie,可以被用来跟踪用户的喜好,帮用户自动登录站点等。Java Plug-in结合web 浏览器可以让applet访问cookie。例如,Java Plug-in让签名applet去查看从web服务器发送到web浏览器的cookie。Java Plug-in5.0文档中谈及对cookie的支持时,给出了几个与cookie交互的代码片段。因为你可能想在applet中测试这些代码片段,还有就是可能你不确定该怎样把它们转变成签名applet,所以下面我给出了一个用来查看cookie的签名applet。在讨论完这些重要的代码后,我将带你学习怎样建立和签名applet。最后,我们会在Firefox web浏览器中运行这个applet。下面就是代码。Listing 4. CookieDetect.java// CookieDetect.javaimport java.awt.BorderLayout;import java.awt.event.*;import java.net.*;import java.util.*;import javax.swing.*;public class CookieDetect extends JApplet implements ActionListener{ private JTextArea txtaStatus; private JTextField txtURL; public void init () { // Build the applet's GUI JPanel pnl = new JPanel (); pnl.add (new JLabel ('Enter URL:')); txtURL = new JTextField (20); txtURL.addActionListener (this); pnl.add (txtURL); getContentPane ().add (pnl, BorderLayout.NORTH); txtaStatus = new JTextArea (10, 40); getContentPane ().add (new JScrollPane (txtaStatus)); } public void actionPerformed (ActionEvent e) { try { URL url = new URL (txtURL.getText ()); URLConnection conn = url.openConnection (); conn.connect (); Map headers = conn.getHeaderFields (); List values = headers.get ('Set-Cookie'); if (values == null) { txtaStatus.setText ('No cookies detectedn'); return; } txtaStatus.setText (''); for (Iterator iter = values.iterator (); iter.hasNext();) txtaStatus.setText (txtaStatus.getText () + iter.next () + 'n'); txtaStatus.setText (txtaStatus.getText () + 'n'); } catch (Exception e2) { System.out.println (e2); } }} CookieDetect.java生成的GUI主要由两个条目构成:一个接受URL的文本框,和一个显示cookie的文本域。无论何时用户按下Enter键和这个文本框获得了输入的光标,文本框的action listener的方法actionPerformed()都会被调用。方法actionPerformed()首先用文本框中的URL建立一个URL对象。然后调用这个对象的openConnection()方法返回一个表示该applet和该URL相互连接的URLConnection对象。继续往下面看,URLConnection()的方法connect()建立这个连接,它的getHeaderFields()方法可以得到不会改变的一组HTTP头和相对应的值,Map的方法get()返回与头Set-Cookie相对应的值组成的List。一个循环列举出了该List中的值;每个值表示一个cookie,被陆续加入文本区域中。假使CookieDetect.java存放在当前目录c:appletsCookieDetect中,完成下面的操作,建立和签名这个查看cookie的applet:· 编译 CookieDetect.java: javac CookieDetect.java. · 把上步得到的CookieDetect.class替换成一个jar文件,jar cvf CookieDetect.jar CookieDetect.class。· 在一个新keytore中创建一个新key:keytool -genkey -keystore ks -alias me。当弹出来后,输入testtest作为keystore的密码,你的姓和名,你所在行业(比如IT),你公司的名字,你所在城市名,所在州或省的名字,你的行业代码 ,不管你刚才输入的信息是否真实,当弹出窗口时选择Yes。当弹出窗口让你输入me的密码 时,单击Enter。这样可以让密码与keystore 中的密码(testtest)相同。所有这些信息都被放在文件ks中,这个文件需要我们自己签名的测试认证。· 创建一个签名的测试认证:keytool -selfcert -alias me -keystore ks。当被弹出后,输入testtest作为keystore的密码。这个认证就被放进ks中了。Alias me (在前一步,这步,和下一步中)提醒你这个认证已被签名,仅仅用来被测试。换句话说,不要在公共站点上用这个测试认证来发布签名applet。· 用这个测试认证来签名这个jar文件:jarsigner -keystore ks CookieDetect.jar me。当弹出后,输入testtest作为keystore的密码。这个工具更新该jar文件的META-INF目录以包含认证信息和CookieDetect.class的一个数字签名。让我们运行这个applet。从本文附的代码中找到CookieDetect.html,然后放进目录c:appletsCookieDetect下。该HTML文件的中包含一个archive属性来标识CookieDetect.jar文件。打开Firefox,然后输入该HTML文件的URL:c:appletsCookieDetectCookieDetect.html。一段时间后,图5的安全对话框就会出现在你眼前。 Figure 5. 安全对话框让你有权信任这个签名的applet。单击yes键响应该安全对话框。然后这个applet被显示。输入URL:http://javaworld.com,然后按下回车。如图6所示,网站JavaWorld 不会发送cookie。 Figure 6. 你不会从 JavaWorld 取得cookie与JavaWorld 相比,网站JavaLobby会发送一个cookie。输入http://javalobby.org,图7中就会显示有这样一个cookie,id 是SESSIONID。 Figure 7. JavaLobby 发送了一个简单的cookie一些网站会发送出大量的cookie,比如像kasssamba。如图8所显示的,该站点发送了4个cookie到web浏览器。 Figure 8. Kasamba 发送了不少的cookie到web浏览器我极力建议你继续去体会cookie的使用,把余下的三段代码(来源于Java Plug-in 5.0文档中对cookie支持的标题)也转换成签名applet。小窍门 访问 http://www.cookiecentral.com/faq/ 可以学到更多关于cookie的内容。 理解 hood 许多人在让Firefox识别Java Plug-in时会遇到困难。说来说去,就是指applet不能运行。通过理解Firefox与Java Plug-in怎样进行交互,你能避开许多类似的麻烦。在后续部分,我会为你讲解Firefox如何探测Java Plug-in,JRE的 NP*.dll 插件文件,和一些被称为OJI的东西。探测Java Plug-in在前面你已经安装了一个简单的JRE(它包含了Java Plug-in),现在要安装Firefox。你可以运行那个浏览器,上网冲浪,打开那些使用了applet的网页,那些applet就会运行起来了。。不久后,你会思考Firefox是怎样找到Java Plug-in,让applet运行起来的。毕竟说来,Firefox只检索它自己的插件列表来查找插件,而JRE把它自己的Java Plug-in放在它自身的bin目录下。在这样的安排下,Firefox怎么可能检测到Java Plug-in呢?当Firefox开始运行时,它的目录服务提供器就接到一个任务,在windows平台上的安装目录中去找adobe Acrobat, Apple Quicktime, Microsoft Windows Media Player, 和 Sun Java plug-in。Java Plug-in的安装目录一经找到,目录服务提供器将会传递以下信息给plugin.scan.SunJRE:用户的个人设置名称和该设置的值(要求的最低JRE版本)。更进一步,security.enable_java 这个用户设置必须存在,而且它的布尔值必须为true。假如plugin.scan.SunJRE 和 security.enable_java存在,还假设security.enable_java的值是true,目录服务提供器会在windows的注册表中列出所有版本号作为HKEY_LOCAL_MACHINESoftwareJavaSoftJava Plug-in的子键。最新版本号识别出Firefox所使用的JRE/Java Plug-in,这个版本号必须要比plugin.scan.SunJRE的值要大或相等.版本号子键自身的JavaHome子键包含了被识别出的JRE根目录路径。目录服务提供器把bin附加在这个目录后,这时Firefox就知道了Java Plug-in的安装路径了。有点糊涂了?我会用一个例子来拨开这一层雾。我的Firefox浏览器给出我的plugin.scan.SunJRE值为1.3。它同时也指定security.enable_java值为真。在启动时,目录服务提供器扫描我的windows注册表;相关的设置如下:HKEY_LOCAL_MACHINE Software JavaSoft Java Plug-in 1.5.0 JavaHome 'C:Program FilesJavajre1.5.0'目录服务提供器列举出所有版本号的子键,在Java Plug-in子键下面,那个子键所示的最高版本号就大于或等于1.3了。我仅有一个子键大于或等于1.3:1.5.0。因此,目录服务提供器含有子键值为1.5.0的JavaHome子键—C:Program FilesJavajre1.5.0—然后把bin附加在这个值的后面。这就意味着Firefox会在目录c:Program FilesJavajre1.5.0bin下去找Java Plug-in。因为Firefox1.0的plugin.scan.SunJRE用户设置用1.3作为它的默认值,所以Java Plug-in版本低于1.3的不会被识别。这就是为什么Firefox只支持Java Plug-in 1.3.0_01和更高的版本。NP*.dll文件仔细查看你的JRE的 bin目录,你会发现不少文件名以NP开头,以.dll结尾的文件。例如,我的平台下就列出了下面这些文件:NPJava11.dllNPJava12.dllNPJava13.dllNPJava14.dllNPJava32.dllNPJPI150.dllNPOJI610.dll 上面列出的文件是Netscape的插件文件。加上你可能在你的JRE的bin目录下发现的其他NP*.dll文件,和也应该被列出的若干个jpi*.dll文件,他们一起构成了Java Plug-in。每个NP*.dll文件有相同的大小,因为他们基本上都是做的同样的事情:它与jpi*.dll文件中的一个协同工作,下载虚拟机,让java环境运行起来。每一个NP*.dll文件能识别一种或多种MIME(多用途网际邮件扩展协议)类型。当遇到某种MIME类型时,这种类型会告诉Firefox去装载一个相应的具体NP*.dll文件。例如,思考下面的标签: 注意type属性的application/x-java-applet;version=1.1 MIME类型。当Firefox遇到这种MIME类型,它就会选择相应的NP*.dll文件。因为NPJava11.dll标记了那种MIME类型,NPJava11.dll会去装载——而不是其他的NP*.dll装载。NPJava11.dll与jpi*.dl文件一起让java环境运行。当Firefox遇见标签时,它到底表示的是哪种MIME类型?我认为当Firefox 遇到 标签时,application/x-java-vm就是MIME类型:测试显示出只有拥有那个MIME类型的NPOJI610.dll会去装载。什么是OJI?你可能已经注意到在NPOJI610.dll中有OJI,想知道这三个字母代表什么。OJI表示Open JVM Integration ,这是个Mozilla project/API,它允许外部的JVM能够插入一个 Mozilla浏览器(就像Firefox这样)。除了没有被绑定在内部虚拟机上,这个浏览器也没有被绑定在sun指定的外部虚拟机上——浏览器能够通过其他途径与虚拟机进行交互,只要这些虚拟机支持OJI。OJI有许多特性,包括允许用户通过web浏览器来显示java主控台。OJI也会更改一个applet的生命周期:一旦一个applet网页被打开,这个applet的init() 和 start()方法就会被调用。为了让你能看到这个过程,先编译Listing 5的 LifeCycle.java源代码,在Firefox下运行这个applet,打开java主空台,然后不停在网页之间进行切换。在你每次进入这个applet网页的时候,你将注意到对这个applet构造器的调用,它表明一个新的LifeCycle对象被生成了。Listing 5. LifeCycle.java // LifeCycle.javapublic class LifeCycle extends java.applet.Applet{ public LifeCycle () { System.out.println ('constructor called'); } public void init () { System.out.println ('init() called'); } public void start () { System.out.println ('start() called'); } public void stop () { System.out.println ('stop() called'); } public void destroy () { System.out.println ('destroy() called'); }} 总结即使讲完上面所有的内容,我也仅仅是做了浅层次的讲解。其实还有很多东西我想写下来。可能只有在以后,我再写另一篇后续文章来完成了。或者你也可以写那篇文章。不管怎样,都让我们继续拓展我们对Sun的 Java Plug-in技术的理解吧。 关于作者Jeff Friesen 是软件发展的自由撰稿人,同时也是C, C++, 和 Java技术的研究员。资源列表 · 下载这篇文章中的代码: http://www.javaworld.com/javaworld/jw-06-2005/plugin/jw-0627-plugin.zip · 浏览Java Plug-in 5.0的文档: http://java.sun.com/j2se/1.5.0/docs/guide/plugin/index.html · 学习Mozilla.org的 nsPluginDirServiceProvider.cpp 目录服务提供器C++ 写的代码 : http://lxr.mozilla.org/mozilla1.7/source/modules/plugin/base/src/nsPluginDirServiceProvider.cpp · 查看 Mozilla.org的 OJI站点 : http://www.mozilla.org/oji/ · 'Plug into Java with Java Plug-in,' Jeff Friesen (JavaWorld, June 1999): http://www.javaworld.com/javaworld/jw-06-1999/jw-06-plugin.html · 查看 Sun的 Java Plug-in 主页: http://java.sun.com/products/plugin/index.html · Jeff Friesen, 'Talk with Me Java,' (JavaWorld, June 2004): http://www.javaworld.com/javaworld/jw-06-2004/jw-0621-talk.html · 非官方的 Cookie FAQ: http://www.cookiecentral.com/faq/ Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd 摘要这篇文章与Jeff Friesen前一篇关于Java Plug-in的文章'Plug into Java with Java Plug-in' (JavaWorld, 6月 1999)是一个系列的。它专注于Firefox Web浏览器的最近的Java Plug-in其
标签: Java
相关文章: