Server-Side DHTML

The "Client-Side DHTML" section of this chapter demonstrated how the html package allows apps on the client side to perform dynamic functions like responding to user input and reading client-side database information. DHTML gives apps many of the same capabilities of an applet while remaining in the HTML domain. On the other hand, client-side apps that use the html package are only accessible from Internet Explorer.

apps based on the html package can also run on the server. Server-side apps that use DHTML have both advantages and disadvantages as compared to client-side apps that use DHTML.

Server-side DHTML apps have access to the same display features as do client-side DHTML apps. In fact, you can use practically identical source code for a server-side app as for a client-side app. However, since server-side DHTML apps don't run within a browser, server-side apps can't respond to user input. Server-side DHTML-generated HTML pages aren't dynamic.

Server-side DHTML apps can only run on the Microsoft Internet Information Services (IIS) and Personal Web Server (PWS) Web servers, which are the only servers that have access to the html package of classes. On the other hand, server-side DHTML-generated HTML pages aren't Internet Explorer-specific. Server-side DHTML pages look like HTML pages that any other Web app might generate. The server-side server restriction is less severe than the client-side browser restriction, because it's much easier to control the type of server than the type of browser.

The net effect of these considerations is that using server-side DHTML is useful under these conditions:

For normal business apps, you can usually control the choices of server and browser. Thus, server-side DHTML is applicable in situations when the second and third conditions are true, and is acceptable when the first condition is true.

Static Server-Side apps

Two types of server-side DHTML apps exist: dynamic apps and static apps. In one sense, as I said previously, no server-side DHTML apps are dynamic. No app of this type can respond directly to user input. However, dynamic server-side DHTML apps are able to generate HTML instructions when the user references the app. This is similar to, but more sophisticated than, the CGI apps mentioned earlier in this chapter.

Static server-side DHTML apps run repeatedly at some time interval. These apps write output to HTML files, and these HTML files can be accessed from browsers. The distinction here is that static server-side apps aren't run at the request of the browser.

It might seem at first that static server-side DHTML apps are less useful than dynamic server-side apps, however, static server-side apps are generally more useful. Consider the example of a company with a number of travelling salespeople. A dynamic server-side app might allow the salespeople to access up-to-the-minute information concerning customers and their telephone numbers. It does this at considerable cost to the server, however. Every time a salesperson calls up the telephone directory, the server must run the dynamic server-side app that queries the database. This is wasteful, given that the customer telephone directory doesn't change from day to day, much less change from minute to minute.

By comparison, the static server-side DHTML app might run every day at midnight, when Web traffic is at a minimum. The static app queries the customer database in order to generate the necessary telephone information in the form of HTML pages. The next day, the salespeople access the updated information with static HTML pages. While the data might be up to one day old, accessing the HTML pages generated by static server-side apps doesn't place any more of a load on the server than conventional HTML pages do.

The following DataServerStatic app demonstrates how such an app might work.

design work

Create the DataServerStatic project in the same DHTML directory you used before, using the Code-behind HTML wizard. Remove the Page1.htm file from the project, because static server-side apps aren't run from a browser at all.

We can use the same TableDatabaseConnection class we used in the DataClientSide app. Open your DataClientSide folder and copy the TableDatabaseConnection.java file to the DataServerStatic folder. (Be sure to copy the file, not to move it.) Visual J Plus Plus v6 adds the file to the DataServerStatic project as soon as the file appears in the DataServerStatic folder.

code

Amazingly, the Class1 class for this app is virtually identical to the client-side version of the class. Copy the Class1.java file from the DataClientSide folder to the DataServerStatic folder, and edit the code so it looks as follows:

import com.ms.wfc.html.*;
import com.ms.wfc.core.*;
import com.ms.wfc.data.*;
import com.ms.wfc.data.ui.*;
/**
 * Demonstrate accessing a local database by using the WFC html package.
 */
public class Class1 extends DhDocument {
 // --------------define the database information------------------
 // …identical to the client-side DHTML version…
 // ---------------end of database info----------------------------
 /**
 * Class constructor.
 */
 public Class1() {
 // Required for Visual J Plus Plus Form Designer support
 initForm(); }
 /**
 * Class1 overrides dispose so it can clean up the
 * component list.
 */
 public void dispose() {
 super.dispose();
 }
 /**
 * Create the same DHTML objects created by the
 * client-side app.
 */
 private void initForm() {
 // …identical to the client-side DHTML version…
 }
 /**
 * Run as a Windows console app. Create a Class1
 * object identical to the client-side Class1 object.
 * Rather than display the results, write the corresponding
 * DHTML to standard output.
 */
 public static void main(String[] args)
 {
 // create the Class1 object
 DhDocument doc = new Class1();
 // wrap the Class1 object in head and body section
 // HTML tags (on the client side this is handled // by the DHTML file that invokes the program) doc.setGenerateTags(true);
 doc.setTitle("Statically Generated Table");
 // now convert the html package commands into
 // conventional HTML, and write the HTML to standard output
 String s = doc.getHTML();
 System.out.println(s);
 }
}


The only difference between this app and the DataClientSide app is the addition of a main() method. As with all Windows apps, execution begins with main(). This method begins by creating a Class1 object. The Class1 constructor invokes the same initForm() method called by the DataClientSide class constructor. Just as before, initForm() queries the database to generate the internal structures necessary to create the HTML instructions displayed by the browser. However, this time the HTML is captured in a conventional String object by calling the DhDocument.getHTML() method. The resulting string is then written to standard output.

One last step is required before you can run the app. Since DataServerStatic will run as a Windows console app, we need to change the deployment format. Save the project, then click the project name with the right mouse button in Project Explorer and choose DataServerStatic Properties from the context menu. In the DataServerStatic Properties dialog box, choose the Launch tab. Select Class1 from the When Project Runs, Load drop-down list, and then select the Launch As A Console app check box. Now choose the Output Format tab, and change the Packaging Type to Windows EXE.

result

Running DataServerStatic.exe from the prompt of an MS-DOS window generates the output shown in Figure 16-5.

Java Click to view at full size.

Screenshot-5. Running the DataServerStatic app generates this HTML code.

While this result isn't very pretty, careful examination of the HTML output reveals the <TR> and <TD> tags that one would expect to see when defining a table.

Now capture the console output and copy it to an HTML file by entering the following DOS command:

DataServerStatic > DSS.htm


Using Microsoft Windows Explorer, navigate to the DataServerStatic folder and run the DSS.htm file. You'll see the same browser display as that shown in Figure 16-6. The browser window output appears identical to the output from the DataClientSide app, but notice that the URL that appears in the Address window is that of the DSS.html file.

Java Click to view at full size.

Screenshot-6. The Internet Explorer browser generates a table from the HTML code that is shown in Figure 16-5.

The same table is generated when you display DSS.htm with the Netscape Navigator browser.

Dynamic Server-Side apps

In principle, a dynamic server-side DHTML app is the same as the static version. However, there is one significant difference between the two. With the static version, the app must run when the user's browser selects a certain HTML page, and the output must be sent directly to the client's browser. Without resorting to CGI, it isn't possible to send the output to a file using conventional HTML. This is possible, however, from Active Server Pages (ASP).

Active Server Pages are HTML pages that contain commands run by the server prior to sending the page to the client's browser. The browser sees no difference in the resulting HTML from any other HTML page.

Often, the purpose of these ASP apps is as simple as inserting the current time and date into the HTML page as the page is sent from the server. However, the capabilities of ASP code extend to Component Object Model (COM) components that have been registered on the server. We'll use this ability of ASP to use COM objects in the DataServerDynamic app.

(Note the following example borrows heavily from an example appearing in one of Microsoft's tutorials.)

design work

Create the DataServerDynamic Code-behind HTML project in the DHTML directory. Just as in the DataServerStatic example, remove the Page1.htm file from the project—we won't need it.

The code for this app and the client-based DataClientSide are virtually identical. Copy the Class1.java and TableDatabaseConnection.java source files from the DataClientSide folder to the DataServerDynamic folder.

ASP can only run registered COM objects, so choose DataServerDynamic Properties from the project name's context menu in Project Explorer. Choose the COM Classes tab and select the Class1 check box. Choose OK. If you now open the Class1.java file, you'll notice the addition of a @com.register directive to the comment appearing immediately above the Class1 declaration. This will register as a COM object the CAB file generated by Class1.

code

Edit the Class1.java file copied from DataClientSide so it looks as follows:

import com.ms.wfc.html.*;
import com.ms.wfc.core.*;
import com.ms.wfc.data.*;
import com.ms.wfc.data.ui.*;
/**
 * Demonstrates accessing a local database using the WFC html package.
 * @com.register ( clsid=<GUID>, typelib=<GUID> )
 */
public class Class1 extends DhDocument {
 // --------------define the database information------------------
 // …identical to the client-side DHTML version…
 // ---------------end of database info----------------------------
 /**
 * Class constructor.
 */
 public Class1() {
 }
 /**
 * Class1 overrides dispose so it can clean up the
 * component list.
 */
 public void dispose() {
 super.dispose();
 }
 /**
 * Create the same DHTML objects created by the
 * client-side app.
 */
 private void initForm() {
 // …identical to the client-side DHTML version…
 }
 /**
 * Return a string representation of the Class1 HTML code. This
 * method is invoked from the ASP page.
 */
 public String generateHTMLRepresentation()
 {
 this.initForm();
 return this.generateHTML();
 }
}


The only differences between the DataServerDynamic and DataServerStatic apps are:

The generateHTMLRepresentation() method first calls initForm() to create the DHTML internal representation of the table output. The method then calls generateHTML(), which generates the HTML representation of the internal structures created by initForm() that is to be sent to the browser.

ASP page

Choose Add Item from the Project menu to add an ASP page to the project. Since ASP isn't one of the options listed in the Add Item dialog box, choose Other, and enter the name Web.asp. (The name of the page is unimportant, as long as it carries the .asp extension.) Notice that in Project Explorer, the Web.asp file has an icon unique to .asp files.

In Source mode, add the following code to Web.asp:

<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE></TITLE>
</HEAD>
<BODY>
<%@ LANGUAGE=VBScript %>
<%
dim svr set svr = Server.CreateObject("DataServerDynamic.Class1")
Response.Write "" & svr.generateHTMLRepresentation()
%>
</BODY>
</HTML>


The CreateObject() method creates an object from the Class1 class of the DataServerDynamic.CAB file. The Response.Write command instructs the server to write the output of the generateHTMLRepresentation() method of Class1 to the HTML file containing the ASP commands. This is the page being sent to the client browser.

result

Build the DataServerDynamic project. Notice the creation of a .tlb type library similar to that generated by the ActiveX projects in . This type library is bundled into DataServerDynamic.CAB and registered as a COM object.

For the next step, you'll need access to an IIS or PWS Web server. (You can install the PWS server from the Microsoft Windows 95 or Microsoft Windows 98 installation disk.) Copy the Web.asp and DataServerStatic.tlb files to a folder accessible from the server. (For the PWS server, this folder is probably C:\Inetpub\wwwroot.) Start the Web server. Now bring up Internet Explorer or another browser and enter http://<local path>/Web.asp as your URL, where <local path> is the root directory for your PWS or IIS installation. (Remember that the COM object must be registered on the same computer that is acting as the Web server.)

The resulting display appears identical to that created by both the DataClientSide and DataServerStatic apps. Comments