用J++创建服务器端组件

J++同C++很相似，都是面向对象语言，Java同C最大区别就在于它的独立平台性，虽然有人争论现在的Internet产品生命周期太短，你根本就没时间在它变得过时之前在不同的平台上编译他们。C++对于J++来说仍有速度优势，虽然之间差距是很小的。

这节将使用Visual J++ 1.1 作为开发环境，因为Java是可移植的，任何基于Windows的Java编辑器都都适用。唯一特殊的方面是你的组件必需注册为一个COM对象，它将引入COM库，使用Javareg来在　Windows NT中注册组件。

注意

COM是Microsoft的一种技术。出于这种原因，为IIS组件编写的代码不能在其它平台上运行。这可能不成问题，因为IIS只是在NT上运行。

Java组件开发过程遵循以下步骤：

1. 安装类库，如果需要的话。

2. 编写源代码。

3. 创建项目。

4. 注册你的组件。

5. 在ASP页中引用组件。

注意

这章将介绍如何用Java来创建组件，而同JavaScript或JScript有很大不同，JavaScript和Jscript都是解释性编程语言，与Java或　J++没有或很少联系。

安装类库

要为ASP编写Java应用程序，你必须首先创建类型库，任何关于　Import asp的引用都会失败，除非你完成这步操作。(import.asp)是一个Java类库，它同C里的以.h结尾的include文件类似。

在Visual J++ IDE中选择Tools|Java|Type Library Wizard，然后选择Active Server Pages 1.0 Library，单击OK产生类库。

内建对象接口

在前一段中安装的类库支持通过IScriptingContext接口与ASP内建对象之间的通信，表28.2列出了类库所提供的接口。这些对象的详细信息将在第三部分Section B-Active Sever Objects中介绍。

表28.2 内建对象接口

接口 | 用途
IApplication Object | 调用应用程序对象的方法和属性
IRequest | 调用请求对象的方法和属性
IResponse | 调用响应对象的方法和属性
IReadCookie | 返回CooKie集合的内容（只读）
IRequestDictionary | 通过IRequest接口实现对Request对象集合的索引
IScriptingContext | 返回同Application，Request,Response，Server或Session 对象的接口
IServer | 调用Server对象的方法和属性
IsessionObject | 调用Session对象的方法和属性
IStringList | 从Querystring,Form或Server集合中返回字符串值
IwriteCookie | 设置Cookie的内容

建立组件

使用Explorer创建一个Asp Unleashed 文件夹，它假设在C盘上以c:\AspUnleashed的形式出现。

启动Visual Studio或J++，选择File|new显示工作区对话框，单击Workspace表栏，输入Chaper28作为工作区名称，将路径设为：c:\AspUnleashed\chapter28，如图28.1所示。（如果你已尝试了Visual Basic例子的话，这个工作区已存在）。

在工作里需要一个Java项目工程，选择File|New，单击Projects表头，从列表中选择Java Project并输入JavaSoaringSites作为项目工程名，如图28.2所示，确保选择Add to Current Workspace单选按钮。

最后创建Java源文件，再次选择File|New，单击Files表头，从列表中选择JavaSource File并输入JsoaringSites作为文件名，如图28.3所示。

图28.1 创建chapter28工作区

图28.2 在chapter28工作区内创建JavaSoaringSites项目工程

列表28.1是一个简单的Java日程表组件，错误-陷阱在例子中省略，为的是突出重点，在列表28.4只将显示用Visual Basic编写的组件代码。

表28.1 JsoaringSites.java

// JSoaringSites// This small Java example demonstrates how to create an// ASP component in Java

import com.ms.com.*;import asp.*;

class JSoaringSites{ IResponse m_iResponse = null; IRequest m_iRequest = null; String m_sReturnString = "";

public void OnStartPage(IScriptingContext objScriptContext) { m_iResponse = objScriptContext.getResponse(); m_iRequest = objScriptContext.getRequest(); }

public void OnEndPage() { m_iResponse = null; m_iRequest = null; }

public void ListSoaringSites(String sState) { Variant vOutput = new Variant(); vOutput.putString("Requested State: "+sState); m_iResponse.Write(vOutput); m_sReturnString = "<P>"; if (sState.equalsIgnoreCase("WA")) { m_sReturnString += "Arlington, WA<BR>"; m_sReturnString += "Burlington, WA<BR>"; m_sReturnString += "Pullman, WA<BR>"; m_sReturnString += "Richland, WA<BR>"; m_sReturnString += "Wenatchee, WA<BR>"; m_sReturnString += "Yakima, WA<BR>"; } else if (sState.equalsIgnoreCase("WI")) m_sReturnString += "<BR>West Bend, WI<BR>"; else m_sReturnString += "No sites found for "+sState; vOutput.putString(m_sReturnString); m_iResponse.Write(vOutput); }}

其中的两行代码是Java 的基本组成元素。import com.ms.com.*和import asp.*语句同C中的include文件相似，这个两语句分别引用了你先前安装的COM和ASP类库。

On Start Page和On End Page是两个特殊的事件，它们在当组件初始化和终止时自动执行。ASP自动调用它们，而不需要你为它们特殊考虑。事实上，这个组件可以根本不改动这两个事件的内容。但是，在这个例子里你可以修改其代码以便特定的需要，例如你可能希望当网页打开时组件初始化就进行数据库打开操作。

通过使用equalsIgnoreCase 我们就可以将任何大小写组合匹配作为有效输入，因此wa,Wa,和WA都可以作为Washington的缩写。

我们的例子中只涉及到两个州的信息，所以通过选择语句可以避免许多不必要的代码，但在现实生活中，不可能用大量的if语句来列出开展滑翔机活动的州，这个组件代码应重新改写使用数据库查询语句，但在这里我们可以这样写

当输入这些代码或从CD上拷贝之后，接下来构建此Java组件，然后将这个组件拷贝到WinNT\Java\TrustLib目录下，以命令行形式显示（确信在TrustLib目录下）：

“

\Program Files\DevStudio\VJ\Bin\Javareg”

/register/class:JsoaringSites/progid:chapter28.JSoaringSites

注意

如果你已经注册登记了组件，不要忘记在登记最近的组件之前首先键入以下的命令行来注销先前的组件：

“

\ProgvamFiles\DevStudio\VJ\Bin\Javareg” /unregister/calss:JsoaringSites/progid:chapter28.JsoaringSites

通过使用OLEView.exe确保没有其它的组件在你的Java\bin中注册。出于某些原因，可能与Visual J++ 1.1不能从所有目录都注册成功组件有关——所以注销工作有时不起作用。如果你在OLEView中发现对这个class的其它引用，唯一的办法是搜索到所有的引用这个class的登记文件，然后手来工地删除它们。每个class有三个引用文件。

技巧

OleView是一个很好的跟踪工具。但有时区分问题很困难，究竟是注册/构造问题，还是ASP的问题呢？当你在OleView中双击一个class时，你创建了COM对象的一个实例。

如果对象注册正确，OleView将显示与组件相联系的COM接口，如果OleView显出一个错误信息，可能是一个构造/注册问题。

注意

在Java1.1或更高版本里，你不需要将你的组件复制到一个公共目录中去，因为注册过程将产生一个你实际所在注册路径的映射，这样你就可以避免将你所有组件都保存在同一公共目录中去时可能碰到的麻烦。因为没有一种工具可以显示组件是在哪个路径下注册的。

以下的两个ASP页将使用组件，第一页是一个简单的表单，用来接受用户输入的不同州的选择。第二页将处理请求并将其传递给Java组件，因为在Java组件中只有两个州（Washigton 和Wisconsin），所以大多数查询简单地返回No Sites found信息。

列表28.2说明了Soaring Sites组件是如何使用的。其中的HTML代码询问用户选择一个要搜寻滑翔运动俱乐部的州，然后用户的请求通过HTML的FORM对象传递到列表28.3的代码。

列表28.2 JavaSoaringSites.asp

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Final//EN"><HTML><HEAD> <TITLE>Soaring Sites Results</TITLE></HEAD>

<BODY BGCOLOR="#FFFFFF"><FONT SIZE="2" FACE="Verdana, Arial, Helvetica">

<CENTER><H1>Soaring Sites</H1></CENTER>

<HR Color="Red"><FORM ACTION="JavaSoaringSitesAction.asp"> Enter a state abbreviation to search for a site: &nbsp; <INPUT NAME="State" SIZE="2"><BR> <INPUT TYPE="SUBMIT"></FORM>

</BODY></HTML>

列表28.3显示了Jsoaring Sites真正的调用过程，HTML代码从REQUEST对象（一个内建ASP组件）获得用户的请求并将信息通过调用ListSoaringSites方法，来传递给在定制的组件。组件本身将格式化的结果以HTML代码形成返回给页面。

列表28.3 JavaSoaringSitesAction.asp

<% Option Explicit %><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML><HEAD> <TITLE>Soaring Sites Results</TITLE></HEAD>

<BODY BGCOLOR="#FFFFFF"><FONT SIZE="2" FACE="Verdana, Arial, Helvetica">

<CENTER><H1>Soaring Sites</H1></CENTER><HR Color="Red">

<%Dim SoaringSitesSet SoaringSites = Server.CreateObject("Chapter28.JSoaringSites")SoaringSites.ListSoaringSites Request("State")Set SoaringSites = Nothing%>

</BODY></HTML>

技巧

你可以跳过组件注册，Microsoft已经将这个功能附加在Java 组件中，通过以下形式实现。

Set SoaringSites=Server.Create Object(

“Java:Chapter28.JsoaringSites”)

当这本书出版的时候，这项功能还没有，所以在这章中的例子没有使用这种增强功能。