Java到JavaScript通信

分享于 

26分钟阅读

Web开发

  繁體 雙語

片尾

本文附带的演示聊天应用程序的思想是我自己的。 我所看到的所有聊天应用程序都是完全基于Java或者基于HTML的。 我的方法是这两者之间的平衡。

  • Java和JavaScript之间的通信技术信息已经从Netscape网站上大量文章中收集到。
  • 我第一次看到'无名小程序'的时候,阅读了Danny的文章。 因此我给了丹尼一个很好的术语。

免责声明

本文讨论的技术是使用 IE 5.0和 Windows 2000专业机器上的Netscape 4.7测试的。 据我所知我可以使用浏览器 4.0 +的版本,但是不能保证这一点,因为我没有时间去测试这些版本。

  • 由于JavaScript是惟一支持out-of-the-box的语言,同时拥有主流浏览器,所以所有脚本代码 Fragments 都使用这种语言。 以前,我在 http://www.ncompasslabs.com 使用了一个商用插件,在Netscape中启用VBScript支持,但是当我去他们的站点验证信息时,该产品不再在那里列出。

介绍

现在我已经经历了两年的现代 of,作为我公司电子商务工具包团队的技术领导者。 我已经了解了好设计的界面和在 Visual C++。Visual Basic等各种环境下工作的实现的意义。 基于接口的编程的功能永远在我脑中,我尝试将它应用到软件工程师的所有内容。

经过过去一年,经验教我们行业应该将所有业务逻辑封装在for对象中。 实际使用相同的功能相比,设计和开发基础设施和业务对象通常需要更高的技能技能。 开发这些对象( 至少在我的组织中)的首选环境是 Visual C++/ATL/STL.,微软也将for作为这些对象的替代开发环境。

这些对象通常被称为 faceless,因为它们实现了很多逻辑,但没有用户界面。 表示层是一个富客户机,它具有向最终用户提供信息和收集信息的逻辑。 这样的客户端就会使用无名对象来做一些有意义的事情。 总的想法是,表示层通常需要大量的自定义,而业务对象不会频繁地变化。 表示层所需的更改也可以使用较少经验的程序员实现。

在浏览器环境中应用相同的原则,使用脚本语言来封装非常复杂的客户端逻辑。 Windows 平台上这些模块的选项是JavaApplet和ActiveX控件/服务器。 本文重点讨论了使用 Java applet实现这个目标,因为applet是浏览器。平台和处理器独立的( 在大多数情况下)。

小程序的简要历史

sunmicrosystems在 1995推出了fanfare的Java小程序。 由于他们增加了在浏览器中显示动态网页内容的能力,小程序马上就在浏览器中出现了,这实际上是 static HTML世界中。

在这些初始日期,使用 Java applet是将动态内容添加到web页面的最佳方式。 微软最初试图用ActiveX控件技术计算sun的提供,但是在网页中使用控件有两个主要问题:

  • 这些是处理器特定的二进制模块,因此不适合作为网页的一部分运行。 万维网之所以如此成功的一个主要原因是,使用W3C标准HTML编写的网页是( 在大多数情况下) 浏览器和处理器无关的。 ActiveX控件在这里范例中不适合。

  • 安全性是一个大问题,因为控件编写器对客户端机器上的资源具有完全访问权限。 签名控件允许任何人查看某个控件是否应该下载到/( 或者幸福地无知) 机器上。

当动态 HTML finally 开始成形时,事情发生了。 文档对象模型( DOM ) 以可以编程组件的形式在网页中公开元素,它们拥有自己的属性和方法集。 尽管在 IE 和Netscape导航器浏览器中实现了动态 HTML,但是以编程方式更改内容的基本主题是很大的。 小程序突然开始看起来陈旧原始。 动态 HTML finally的认可以,为新的复杂的动态网页设置了音调。

在浏览器中使用Java小程序有几个优点如列出的below

  • 小程序在多个浏览器,平台和处理器上工作( 在大多数情况下)。

  • Java语言是一种具有强大构造的类型语言。
  • JDK带有许多有用的类,通常只在高级类库中找到。
  • 安全性被设计成技术,小程序在默认情况下在沙箱中运行。 若要破坏沙箱的限制,必须对小程序进行签名。
  • 小程序可以传递给web服务器,发送自定义消息,上载/下载 等等 签名的小程序。
  • 使用'浏览器源视图'选项无法查看小程序代码,从而保护知识产权。
  • Java. class 文件的大小很高,因此可以快速下载。

使用小程序的缺点是

  • 在浏览器会话中,小程序是第一次使用它们显示或者页面以后刷新的时候下载。 小程序代码不在浏览器会话之间的客户端计算机上。 这在大多数情况下都可以被认为是一个优势。

  • 初始化小程序需要很长时间。
  • 由于 Java. class 文件是由Java虚拟机( JVM ) 解释的字节代码,小程序运行速度比本机代码慢。
  • 小程序只是网页上的一个实际地产,并且没有无缝集成到页面内容中。 级联样式表不直接影响小程序占用的矩形区域。
  • Netscape Navigator 4.x 有十个( 10 ) 活动小程序限制。 我不知道 IE 4.0 + 有任何这样的限制。

使用Java小程序的快速概述

Java小程序包含在带有applet标签的HTML页面中。 W3C站点上 HTML 4.01规范的第 13.4部分详细地记录了这个标记。 它还提到这个标记是不赞成使用 <对象> 标记的。

包含小程序的示例HTML页面显示为 below:

<html><BR><head><BR><title>Calculator</title><BR></head><BR><body><BR><appletid="Calculator"width="300"height="500"code="Calculator.class"codebase="."><BR><paramname="InitialMode"value="Normal"><BR></applet><BR></body><BR></html>

在 上面 示例中使用的属性解释为 below。

Id

小程序实例的标识符。 客户端脚本代码可以使用这里标识来引用小程序。

宽度

这里属性指定小程序显示区域(。排除小程序创建的任何 Windows 或者对话框)的初始宽度。 尽管我已经成功地使用了"of"部分中提到的浏览器的宽度,但是建议使用( 0 ) 值 1.

高度

这里属性指定小程序显示区域(。排除小程序创建的任何 Windows 或者对话框)的初始高度。 就像宽度属性一样,建议使用 1值作为最小高度。

代码

属性指定类文件的NAME,它的中包含编译的小程序子类或者获取类的路径,包括类文件本身。 它是关于小程序美国代码库的。

代码基

这里属性指定小程序的基 URI。 如果未指定这里属性,则它默认为与当前文档相同的基 URI。

只需要代码。宽度和高度属性。

<参数> 标记包含 NAME 值对,它允许在首次启动时配置小程序。

调用 上面 applet上的方法的示例JavaScript函数显示为 below。

<scriptlanguage="Javascript"><BR>function SetCalculatorMode(Mode)<BR>{<BR> document.Calculator.SetCalculatorMode (Mode);<BR> <FONT
 COLOR="GREEN">// Alternative way to reference the applet.</FONT><BR><FONT COLOR="GREEN">// document.applets[0].SetCalculatorMode(Mode);</FONT><BR>}<BR></script>

劳动分工

在本文介绍中,我建议了一种方法,它的中复杂的浏览器侧处理是由JavaScript代码管理的。 这种方法需要Java与JavaScript之间的双向通信。 接下来的几个段落将调查可用选项。

从JavaScript代码访问由 Java applet公开的public 成员和函数很简单,如前一节中的SetCalculatorMode() 函数所示。 文档中的小程序被称为使用/NAME 或者使用指向小程序 Collection的索引。

比如,

document.Calculator.SetCalculatorMode(Mode);<BR> <FONT
COLOR="GREEN">// or</FONT><BR> document.applets[0].SetCalculatorMode(Mode);

使用 netscape.javascript.JSObjectnetscape.javascript.JSException 类实现其他 direction ( Java到 JavaScript ) 中的通信。 为了找出这些. class 文件所在的位置,我搜索我的硬盘,寻找包含文本"jsobject"的所有文件。 令我惊讶的是,这些文件在许多不同的应用程序中被广泛使用,包括任何可视化Interdev项目的脚本库。

如果你的机器上安装了 Netscape +,这些。 在 Java40.jar 文件中可以找到类文件,该文件本身位于 <导航器安装目录> communicatorprogramjavaclasses目录中。

我还在 <Windows 安装目录> JavaPackages目录中的4 个不同的. zip 文件中找到这些. class 文件。 这些. zip 文件显然是由微软产品安装的,因为它们包含许多 com.ms 包。 要点是这两个类都可以使用浏览器,你可以将CLASSPATH环境变量设置为任何 上面 路径。 另一种方法是使用等效的工具将这些文件从. jar 或者. zip 文件提取到你的小程序目录。

JSObject类

为了更好地理解这个类的用途,包含了JSObject类'成员函数of的简短描述。

public static JSObject getWindow ( 小程序小程序)

这里 static 方法为包含给定小程序的窗口返回一个 JSObject。 比如,

JSObject MainWindow = JSObject.getWindow ( this );
public 对象调用( 字符串方法,对象参数 [ ] )

这将从Java小程序中调用一个JavaScript方法。 比如,

JSObject MainWindow = JSObject.getWindow ( this );<BR>String Arguments[ ] = {"90", "2"}; <FONT
 COLOR="GREEN">// {"Percent complete","Time remaining"}</FONT><BR>MainWindow.call ("UpdateProgressIndicator", Arguments );
public 对象评估( 字符串s )

这里方法计算JavaScript表达式。 表达式是一个JavaScript源代码,它将在 this 提供的上下文中是 evalauted。 比如,

JSObject MainWindow = JSObject.getWindow ( this );<BR>JSObject UserName = MainWin.eval ( "document.UserInfoForm.UserName" );
public 对象 getMember ( 字符串 NAME )

这里方法检索JavaScript对象的索引成员。 在JavaScript中等效于 this.name。 比如,

JSObject MainWindow = JSObject.getWindow ( this );<BR>JSObject DocumentPage = (JSObject)MainWindow.getMember ( "document" );<BR>JSObject UserInfoForm = (JSObject) DocumentPage.getMember ( "UserInfoForm" );<BR>JSObject UserName = (JSObject) UserInfoForm.getMember ( "UserName" );
public 对象 getSlot ( int索引)

这里方法检索JavaScript对象的索引成员。 在JavaScript中等效于 this [index]。 比如,

JSObject MainWindow = JSObject.getWindow ( this );<BR>JSObject DocumentPage = (JSObject)MainWindow.getMember ( "document" );<BR>JSObject Applets = (JSObject) DocumentPage.getMember ( "applets" );<BR>Object theApplet = Applets.getSlot ( index );
public void removeMember ( 字符串 NAME )

这里方法移除JavaScript对象的命名成员。

public void setMember ( 字符串 NAME,对象值)

这里方法设置JavaScript对象的命名成员。 它与JavaScript中的this.name = value 等价。 比如,

JSObject MainWin = JSObject.getWindow ( this );<BR>JSObject DocumentPage = (JSObject) MainWin.getMember ( "document" );<BR>JSObject UserInfoForm = (JSObject) DocumentPage.getMember ( "UserInfoForm" );<BR>JSObject UserName = (JSObject) UserInfoForm.getMember ( "UserName" );<BR>UserName.setMember ( "value", "Jeremiah S. Talkar" );
public void setSlot ( int索引,对象值)

这里方法设置JavaScript对象的索引成员。 它与JavaScript中的this[index] = value 等价。

public 字符串 toString ( )

这里方法将JSObject转换为字符串。

如示例所示,JSObject类的public 方法并不局限于从JavaApplet中调用JavaScript函数,而不限于调用 上面。 它们还使applet能够直接操作文档对象模型( DOM ) 元素。

有关这些类的完整文档可以在 http://developer.netscape.com/docs/manuals/communicator/jsref/pkg.htm 获得。

文档还解释了如何在Java和JavaScript之间处理数据类型。

MAYSCRIPT属性的意义

即使applet使用JSObject调用JavaScript函数或者直接访问文档对象模型,如果 <applet> 标记不包含MAYSCRIPT属性,JSObject方法也会失败。 这使得页面设计者可以确定一个小程序是否可以调用 JavaScript。

无名小程序之间的通信

在web页面中使用不可以重用的Java小程序时,一个小程序可以能需要直接与另一个。 这样的调用也可以通过中间JavaScript函数来实现,但是知道所有可用选项总是更好。

java.applet 包中的AppletContext接口提供一个小程序访问小程序执行上下文,如浏览器运行的浏览器,小程序所在的网页以及相同页面上的其它小程序。

例如这里有一个包含两个小程序的HTML页面。

<html><BR><head><BR><title>Communication between applets</title><BR></head><BR><body><BR><appletcode="CircleArea.class"name="CircleArea"width=1 height=1><BR></applet><BR><appletcode="PICalculator.class"name="PICalculator"width=1 height=1><BR></applet><BR>...<BR></body><BR></html>

下面的代码显示AppletContext对象的用法。

AppletContext context = getAppletContext();<BR> PICalculator PIApplet = (PICalculator) context.getApplet ( "PICalculator" );<BR> PIApplet.getValueOfPI();

另一个选项是使用 AppletContext::getApplets() 方法返回一个枚举来访问文档中的所有小程序。 尽管applet之间的通信是标准 JavaApplet API的一部分,但在所有启用的浏览器中都不支持它。 其他小程序的硬编码名称也不灵活。 最好的方法是使用中间的JavaScript函数来处理这种通信。

Java中的IUnknown::QueryInterface

类 object 是类层次结构的根类. 每个类都有对象作为超类。 所有对象( 包括数组) 都实现这里类的方法。 Object::getClass() 方法返回'类',它有许多有用的函数来发现Java类本身的细节。 尽管详细解释超出了本文的范围,但是我想指出 getInterfaces() 方法支持Java类实现的接口。

我没有尝试在JavaScript中调用 getClass() 方法,因此无法对它的进行评论。 但是,使用基础结构类型 applet,可以很容易地使用这里功能编写脚本代码。

安装示例文件

本文的示例代码打包在 Java2JavaScript.zip 文件中。 示例文件演示了一个聊天应用程序,它被简化为在客户端端路由消息。 在实际生活中,参与聊天的用户在单独的机器上,并将消息发送到服务器。

构成该示例的文件包括

ISession.java

定义ISession接口的源文件。

ISession.class

ISession接口的Java字节代码。

ChatClient.java

演示ChatClient小程序的源文件。

ChatClient.class

ChatClient小程序类的Java字节代码。

CompileChatClient.bat

java源文件的原始 makefile。

TestChatClient.htm

承载ChatClient小程序的HTML文件。

JSObject.class

JSObject类的字节代码。

JSException.class

JSException类的字节代码。

安装和运行示例程序的步骤如下

  • 在运行个人Web服务器或者Internet信息服务器实例的机器上,将 Java2JavaScript.zip 文件解压到你选择的目录中。

  • 确保JSObject和JSException类文件在安装目录下的netscapejavascript子目录中可用。
  • 右键单击安装目录并选择'属性'。
  • 单击'网络共享'选项卡并选择'共享这里文件夹'单选按钮,接受弹出对话框中显示的默认'虚拟目录'。
  • 最后,启动 IE 4.0 + 或者 Netscape + Navigator +的实例,输入 URL http://<计算机名称>/<虚拟目录>/testchatclient。htm。

在两个输入字段输入一些文本并单击相应的'发送'按钮以查看聊天窗口中显示的消息。

示例代码说明

聊天应用程序是网络上流行的协作机制。 我所看到的两种聊天应用程序是

  • 管理用户界面以及与服务器的所有通信的Java小程序。

  • 每几秒自动刷新一个HTML页面以显示自上次刷新后发送的任何新聊天消息。

最近,我必须为我们的电子商务产品实现一个生产质量聊天应用程序。 经过大量的思考,我决定使用混合方法。 首先,Java是一个实现ISession接口的无名小程序。

publicinterface ISession<BR>{<BR><FONT
 COLOR="GREEN">// Type is used to differentiate the actual message string </FONT><BR><FONT COLOR="GREEN">// and can be set to 'Text', Hyperlink' etc.</FONT><BR><BR><FONT COLOR="GREEN">// Should be invoked first to indicate to the server that a </FONT><BR><FONT COLOR="GREEN">// new person has joined the chat.</FONT><BR> public int BeginSession(String strAuthor, String strOptions, String strType, String strMessage);<BR> <BR><FONT COLOR="GREEN">// Should be invoked when the author wants to exit the chat.</FONT><BR> public int EndSession(String strAuthor, String strType, String strMessage);<BR><BR><FONT COLOR="GREEN">// Used to send the chat messages.</FONT><BR> public int SendMessage(String strAuthor, String strType, String strMessage);<BR>}

我已经修改了这个接口的生产版本的聊天应用程序,包括 EndSession() 参数和 SendMessage(),以及。 这是因为我的演示使用一个小程序来从两个不同的作者聊天聊天消息。

ChatClient.java 文件是tmodel接口实际的实现。 浏览器调用 init()start()stop(),如果它们被实现的话。 表示文档窗口的JSObject在 init() 方法中获取。

<FONT
 COLOR="GREEN">// Get the JavaScript window that will have the various scripts that this applet will call.</FONT><BR> m_JScriptWin = JSObject.getWindow(this);

由于 Java applet调用两个不同的JavaScript函数,我决定允许web开发人员将这些函数的名称指定为 paramerters。

m_strMessageHandler = getParameter("MessageHandler");<BR>m_strErrorHandler = getParameter("ErrorHandler");

BeginSession()EndSession() 是只调用 SendMessage()的虚实现。

SendMessage() 调用在m_strMessageHandler成员变量中指定了它的NAME的JavaScript函数。 默认值为"handlesessionmessage"。 这里显示相关代码。

if (m_JScriptWin!= null)<BR>{<BR> String Arguments[] = {strAuthor, strType, strMessage};<BR> m_JScriptWin.call(m_strMessageHandler, Arguments);<BR>}

HandleSessionError() 调用一个JavaScript函数,它的NAME 在 m_strErrorHandler 成员变量中指定。 默认值为"handlesessionerror"。

TestChatClient.htm 文件处理聊天的演示内容。 小程序使用 <小程序> 标签在页面上包含。

<applet id="ChatApplet" width="1" height="1" code="ChatClient.class" codebase="." VIEWASTEXT mayscript><BR><param name="MessageHandler"value="HandleSessionMessageEx"><BR><param name="ErrorHandler"value="HandleSessionErrorEx"><BR></applet>

这些参数为applet调用的两个JavaScript函数指定名称。 除了默认的名称之外,我还指出了这些名称的灵活性。

页面上的两种形式模拟两个人互相聊天。 相应的HTML是直接的。

实际消息本身显示在 ChatMessages <div>中。 对于 IE,我使用 table 对象模型在单独的行中显示每个消息。 因此 上面 DIV中的ChatMessagesTable定义。

finally,HandleSessionMessagesEx() JavaScript函数处理所有的表示方面。 在 IE 中,将新行添加到发送的每个消息的ChatMessagesTable table 中。 如果需要,将显示滚动条。 在Netscape导航器中,我将新消息附加到message变量,并使用后者更新 ChatMessages <div>。 由于滚动条不能自动显示在 Netscape <DIV> ( 这其实是个层) 中,所以我将显示在顶部收到的最后一条消息。 我已经找到了关于如何在导航器中支持层的滚动条的文章,但这与这个演示不相关。

final 思想

本文试图介绍一些实现浏览器端逻辑的( 整齐) 技术。 就像我前面提到的,JSObject 被许多应用程序( 包括微软公司) 广泛使用。 在这里,仔细考虑你的个人情况,以确定这里所提供的技术是否适用。

对于本文附带的示例示例,我觉得允许在 javascript/dhtml中实现聊天功能。 使用 dhtml/javascript也更容易定制用户界面。 此外,它允许更强大的呈现技术,看起来与页面内容的其余部分一致。

在这里应用程序的生产版本中,我添加了对在参与者机器上交换超链接的支持。

欢迎任何反馈。


COM  JAVA  Javascript  COMM  通讯  
相关文章