★ wanayoo — archive 1999 http://www-4.ibm.com/software/ebusiness/buildapps/understand.htmlNouvelle recherche | Portail wanayoo
IBM
Shop Support Downloads
Home Products Consulting Industries News About IBM
Search
 

 
 

 
 

IBM Application Framework for e-business -
Understanding Technology Choices

Table of Contents

Introduction
Thin Client
Web Application Model
Summary
References
Appendix A
Notes
Listings

Introduction

You have decided to use the Internet and/or Intranet to put your business processes on-line. And, you have wisely chosen IBM's Application Framework for e-business (an excellent introduction to which can be found at http://www.ibm.com/developer/features/framework/framework.html) as your platform. Now what?

The Application Framework for e-business addresses many important issues in the development of e-business solutions. The Framework is prescriptive; it maximizes the use of Internet and other open standards and protocols versus proprietary technologies. However, developing in the context of the Framework still leaves a choice of technologies (among those Internet and open systems) which can dramatically affect the performance, robustness and usability of a solution. After reading this paper, you will better understand the many choices of client and server technologies.

The first major section, Thin Client, is a detailed discussion of available client side technologies. At the end of each subsection you will find recommendations regarding specific client side technologies and their use in relationship to the IBM Application Framework for e-business.

The second major section, Web Application Model, addresses the Web application server components of an e-business application. Various technologies are shown via concrete implementation examples for the interaction controller, UI logic and business logic components. The examples are drawn from an on-line banking demonstration program called "Freeside". The Freeside demo is an example of an e-business application developed using the IBM Application Framework for e-business. You can benefit from the analysis and design work done by the developers of this application through looking at the provided code listings and reading the discussions of the technology choices.

In the spirit of providing something for everyone, you will get some helpful information development guidelines for creating your web pages in Appendix A.


Thin Client

e-business applications combine Web application servers, Web clients (such as Web browsers), and standard Internet protocols to facilitate access to data and applications across a single enterprise or between multiple enterprises. There are many technologies that can be used during the development of the client side of a Web application in an e-business application. These include Java, TCP/IP, HTTP, HTTPS, HTML, DHTML, XML, MIME, SMTP, IIOP, and X.509, among others. Often, success of the project and future adaptability hinge upon which technologies are incorporated. This section discusses which of these technologies are appropriate for client side Web applications. IBM's goal is to encourage developers to make the client side of Web applications rather lightweight. This is usually characterized as a "thin client".

The thin client consists of a Java enabled Web browser and a Java Virtual Machine (JVM), a TCP/IP stack and (potentially) an encryption library. With this capability, the client provides three key benefits for e-business applications based upon IBM's Application Framework for e-business.

  1. Any browser has the potential to run a Web application that is based upon the thin client model.
  2. The client part of the Web application is small and downloads quickly.
  3. The server is able to tailor the HTML returned to the client based upon client or user attributes.

There are several different client technologies, such as HTML, DHTML, Java applets, and JavaScript, available to the developer. The design of the client side of a Web application varies considerably depending upon which technology is employed. The choice of client side technology must be made in concert with the server side technology choice. In fact, the technology choice must be made as part of an end-to-end design.

The table below identifies the technologies that currently support the most clients (left) to the fewest clients (right):
 
Web Client HTML 3.0 with Forms Java 1.0.2 Simple DHTML with JavaScript 1.1  Java 1.1 Complex DHTML with Non-standard JavaScript
Netscape 3 Supported Supported Supported Not available Not available
Netscape 4 Supported Supported Supported Most functions Support with JavaScript 1.2
Internet Explorer 3 Supported Supported Supported Not available Not available
Internet Explorer 4 Supported Supported Supported Most functions Support with JScript and VBScript
HotJava  Supported Supported Not Available Supported Not Available
Network Computers (Java Based) Supported Supported Not Available Supported Not Available

Web Browser

Thin clients contain Web browsers that vary significantly in the level of support for client technologies. Web browsers support different levels of Java, JavaScript, HTML, and DHTML. The less control the developer has in specifying the level or type of browser required, the more basic the client code must become. If an e-business application is to be accessed by users with varying browser capabilities, then to be conservative the client is often written in HTML. The other end of the spectrum is to use the advanced capabilities of DHTML, which are very browser specific. This approach may only be appropriate for intranet applications where the browser and version installed are tightly controlled.

HTML

Many e-business applications are assembled strictly using HTML. This has the advantage that the client side Web application can be a simple HTML browser, enabling a less capable client to execute an e-business application. Because most Web browsers can display HTML version 3.2, this is the lowest common denominator for building the client side of an application. A good introduction to HTML can be found at http://www.w3.org/MarkUp/.

The HTML specification defines UI elements for text with various fonts and colors, lists, tables, images, and forms (text fields, buttons, checkbooks, radio buttons). These elements are adequate to display the user interface for most applications. The disadvantage, however, is that these elements have a generic look and feel, and they lack customization. As a result, some e-business application developers augment HTML with other UI technologies to enhance the visual experience.

JavaScript

ECMA, a European standards body, has published a standard (ECMA-262) which is based on JavaScript (from Netscape) and JScript (from Microsoft) called ECMAScript. The ECMAScript standard defines a core set of objects for scripting in Web browsers. JavaScript is a cross platform, object oriented scripting language which is a superset of ECMAScript. It is comprised of the core ECMAScript objects that run on both Web browsers and servers, as well as a set of unique client specific and server specific objects. The core objects include array, date, math, number, and string. On the client side, there are document, form, frame, and window objects. These core objects enable the manipulation of HTML documents (checking form fields, submitting forms, and creating dynamic pages), and the manipulation of the browser (directing the browser to load other HTML pages, display messages, etc.).

To address various needs of the client side of a Web application, Netscape and Microsoft have built upon ECMAScript in their implementations of JavaScript 1.2 by adding new browser objects. Because Netscape's and Microsoft's extensions to the standard are different from each other, any script written must detect the browser being used, and select the correct statements to run. You can detect the browser information using the navigator object as shown in Listing 1.

However, versions 3.0 and earlier of both Netscape and Microsoft browsers don't support these new extensions. Thus, to ensure that a script can be run on most browsers use JavaScript1.1 which contains the elements of ECMAScript version one. You can find the ECMAScript Language Specification at http://www.ecma.ch/stand/ECMA-262.htm for the latest ECMAScript version information.

Dynamic HTML (DHTML)

DHTML allows a high degree of flexibility in designing and displaying a user interface. In particular, DHTML includes cascading style sheets (CSS) that enable different fonts, margins, and line spacing for various parts of the display to be created. These elements can be accurately positioned using absolute coordinates. To learn more about CSS take a look at http://www.w3.org/Style/CSS/.

Another advantage of DHTML is that it increases the level of functionality of an HTML page through a document object model and event model. The document object model (see http://www.w3.org/DOM/) enables scripting languages such as JavaScript to control parts of the HTML page. For example, text and images can be moved about the screen, and hidden or shown, under the command of a script. Also, scripting can be used to change the color or image of a link when the mouse is moved over it, or to validate a text input field of a form without having to send it to the server.

Unfortunately there are several disadvantages with using DHTML. The greatest of these is that two different implementations, Netscape and Microsoft, exist. A small, basic set of functionality is common to both, but differences appear in most areas. The significant difference is that Microsoft allows the content of the HTML page to be modified by using either JScript or VBScript, while Netscape allows the content to only be manipulated (moved, hidden, shown).

A second disadvantage with DHTML is that only the 4.0 versions and above of the Netscape and Microsoft Web browsers support it. Depending upon the composition of the clients accessing an e-business application, some customers could be excluded.

Because of browser compatibility issues, complex DHTML using browser specific extensions is not recommended in environments where mixed levels and brands of browsers are present unless the application can be made browser and version sensitive. However, complex DHTML may be appropriate in intranet environments where there is more control over installed browser versions.

Java Applets

The most flexible of the UI technologies that can be run in a Web browser is offered by the Java applet. Java provides a rich set of UI elements that include an equivalent for each of the HTML UI elements. In addition, because Java is a programming language, an infinite set of UI elements can be built and used. There are many widget libraries available that offer common UI elements, such as tables, scrolling text, spreadsheets, editors, graphs, charts, etc.

A Java applet is a program written in Java that is downloaded from the Web server and run on the Web browser. The applet to be run is specified in the HTML page using an APPLET tag:

<APPLET CODEBASE="/mydir" CODE="myapplet.class" width=400 height=100>
  <PARAM NAME="myParameter" VALUE="myValue">
</APPLET>

For this example, a Java applet called "myapplet" will run. An effective way to send data to an applet is with the use of the PARAM tag. The applet has access to this parameter data and can easily use it as input to the display logic. To learn more about applets take a look at http://www.javasoft.com/applets/index.html.

Java can also request a new HTML page from the Web application server. This provides an equivalent function to the HTML FORM submit function. The advantage is that an applet can load a new HTML page based upon the obvious - a button being clicked, or the unique - the editing of a cell in a spreadsheet.

A characteristic of Java applets is that they seldom consist of just one class file. To the contrary, a large applet may reference hundreds of class files. Making a request for each of these class files individually can tax any server and also tax the network capacity. However, packaging all of these class files into one file reduces the number of requests from hundreds to just one. This optimization is available in many Web browsers in the form of either a JAR file or a CAB file. Netscape and HotJava support JAR files simply by adding an ARCHIVE="myjarfile.jar" variable within the APPLET tag. Internet Explorer uses CAB files specified as an applet parameter within the APPLET tag. In all cases, executing an applet contained within a JAR/CAB file exhibits faster load times than individual class files. While Netscape and Internet Explorer use different APPLET tags to identify the packaged class files, a single HTML page containing both tags can created to support both browsers. Each browser simply ignores the other's tag.

A disadvantage of using Java applets for UI generation is that the required version of Java must be supported by the Web browser. Thus, when using Java, the UI part of the e-business application will dictate which browsers can be used for the client side e-business application. As discussed before this disadvantage may not be significant for many intranet applications

A second disadvantage of Java applets is that any classes such as widgets and business logic that are not included as part of Java must be loaded from the Web server as they are needed. If these additional classes are large, the initialization of the applet may take from seconds to minutes, depending upon the speed of the connection to the internet.

Because of the above shortcomings the use of Java applets is not recommended in environments where mixed levels and brands of browsers are present. Small applets may be used in cases where HTML UI elements are insufficient to express the semantics of the Web application user interface. If it is necessary to use an applet, care should be taken to include UI elements that are core Java classes whenever possible. Larger applets may be appropriate for intranet applications where users are LAN attached.

While we believe that HTML is the appropriate technology for many thin client e-business applications, this does not mean that an application based on the Framework consists of static, hardcoded, hand written HTML pages with an occasional CGI-BIN program. Just the opposite! The next section will describe how HTML is used and generated via server side technologies such as Java Server Pages and servlets.


Web Application Model

The best way to think of a Web application is as a series of interactions between a client and a particular Web site. The entire Web interaction process begins with a single page displayed in the browser. The user clicks on a button or link on the page causing a request to be sent to the Web application server. The request is processed on the Web application server and a new page is sent back showing the results of the request and presenting buttons or links for the next request. Thus the Web application consists of a set of processing steps or interactions, each of which gets a request generated from a page and each of which must produce a response in the form of a page that will serve as the input for subsequent interactions.

If we examine a single interaction at the next level of detail, we see a common set of processing requirements that can be nicely mapped to the classical model/view/controller paradigm as follows:

Observing this mapping is important because experience has shown that the different types of logic frequently require different development skills and tools, and often need to evolve on different schedules. To do this, it is critical to maintain a clean separation between the different types of program logic. The Framework recommends that the business logic be wrapped with JavaBeans that it calls command beans. A command bean should usually represent a single function supported by the business logic. Its usage paradigm is: create the bean; initialize by setting the bean's properties; perform by calling the bean's methods; and inspect by getting the values of the bean's properties. Using command beans of this form provides several benefits including:

The remainder of this section will discuss the Web application elements of interaction controller, UI logic, and business logic in more detail. The business logic section will focus on the use of command beans.

Interaction Controller

The easiest way to think about the responsibility of the interaction controller is that it is the piece of code that ties client independent business logic to the other elements of a Web application. Some typical functions performed by the interaction controller are:

The Framework supports the development of interaction controller logic using either Java servlets or Java Server Pages (JSP) technology. Both of these implementation mechanisms have significant advantages over using CGI-BIN or Web server plugins. You will need to decide whether to use JSPs or servlets or both in your interaction controller. Another design issue is the cardinality of the relationship between interactions and interaction controllers (reference [2] contains a detailed discussion of this issue.)

The chief advantage Java Server Pages have over Java servlets is that they are closer to the presentation medium. A Java Server Page is an HTML page. It contains all the HTML tags that Web authors are familiar with, and presents them in the same way as ordinary hypertext, allowing an author to leverage favorite HTML design tools. Certainly, one could write a servlet to generate complex, beautiful Web pages, but layout tools such as NetObject's Fusion make the job much easier.To learn more about JSPs visit http://www.javasoft.com/products/jsp/.

A JSP is HTML, but may also contain fragments of Java code selecting which pieces of the layout are visible and which are not. These code fragments may call out to JavaBeans or Enterprise JavaBeans (see [Enterprise JavaBeans note]) to access reusable components and back-end data. The code fragments may be reinforced by expressions, fragments of Java code that return some value (e.g. a property on a bean.) If the amount of code on a page is relatively small, that is, the page is primarily for presentation, JSP offers a way to focus on the artistic creation of the page by compiling the page into a Java servlet for the author.

Servlets make the Java code much easier to read and therefore maintain when the amount code is proportionately larger than the amount of HTML on the page. Unlike a JSPs, servlets are compiled before being usable in the runtime. They do not require a full application server runtime during the compile phase. Because servlets are deployed as .class files they are more attractive than JSPs in instances where you do not want the source code of your Web application available on the Web server.

There are compelling reasons to use the JSP wherever possible, factoring business logic into JavaBeans, and leaving JSP scripting to simple flow of control and bean property accesses. This enables rapid development of JSP, and the maintenance benefits of the JavaBean component model.

The following sections describe typical functions performed by the interaction controller in more detail with code examples taken from the Freeside demo.

Request Validation

Input validation can occur on the Web application server implemented in JSP or servlet form in Java; however, a performance gain can often be realized if this function is performed in JavaScript on the client preventing unnecessary exchanges between the client and the Web application server. An example of using JavaScript to verify a bank transfer is shown in Listing 2.

Privilege Verification

An e-business application may wish to obtain login information from users that have not properly logged into the application. There is a variety of choices for assigning user privileges: Web servers, such as Apache, have authentication and access control services; most current operating systems have authentication and access control services; many applications "roll their own" authentication services. The example in Listing 3, of the "roll your own" variety, shows JSP logic which redirects a user to the login page if the user request does not contain a session object or if the session object does not contain required user authentication information (see [Session object note] for a description of the session object.)

Mapping Requests to Business Logic Input Properties

This is where command beans come into play. Command beans form a stable boundary between the business logic and user interface. The interaction controller will map input from the user request to command bean properties. The command bean hides the business logic and data behind its properties allowing the business logic to evolve independently of the user interface and vice versa. The interaction controller may execute multiple command beans to gather output which it will then route to the UI logic.

The environment for command execution is called the command target. Command targets can be located on a local server which simply calls the command bean's perform method, or located on a remote server which requires serializing the command bean and shipping it to a remote server for execution. However, the interaction controller only needs to be aware of the command bean interface to execute commands. There is a detailed discussion of the components of the command bean infrastructure in the Separation of UI and Business Logic section.

The code segment in Listing 4 shows the mapping of the user ID from the customerInfo object to the "CustomerID" input property of the viewAccounts command bean.

Invoke UI Logic

Once a command bean has executed it is the job of the interaction controller to invoke the proper user interface logic to convey the result information to the user. The code segment in Listing 5 executes the transfer funds command bean and invokes the correct user interface logic via the sendRedirect method of the response object.

UI Logic

The UI logic, the view component of the application, is responsible for generating the HTML page that will be returned to the client. Like interaction controllers, the Framework supports the development of UI logic using either servlets or JSP technology. Because JSP allows HTML and Java to be mixed on the same page, it is most often the best choice for the UI logic implementation. JSP offers a template based approach, supported by visual authoring tools, for integrating dynamic data into HTML pages.

In many cases, the interaction controller will pass dynamic data to the UI logic for formatting. In other cases, the UI logic will invoke business logic directly to obtain dynamic data. It makes sense to have the interaction controller pass the data when it has already obtained it and when the data is an essential component of the contract between the interaction controller and the UI logic. In other cases, the data needed is not an essential part of the interaction, and can be obtained independently by inserting calls to business logic directly in the UI logic.

Once the UI logic has obtained the dynamic data, either from the interaction controller, or via its own logic, it will typically format the data. This can be done several ways. The simplest mechanism is where the data is formatted using simple scripting inside the display page. An alternative is to develop reusable script or Java object formatting components that will take a data set and return formatted HTML.

The code segment in Listing 6 generates HTML to serve to the client based on the results of the execution of the viewAccounts command bean. The viewAccounts output property which is an array of account information beans is displayed in a table.

Java/HTML Separation in JSPs

In production environments where HTML coding and JSP coding are handled by two different individuals, it's a good idea to separate the Java code from the HTML as much as possible. If the Java is intermixed with the HTML, the HTML coder might inadvertently modify the Java. Or vice versa.

There are 3 basic ways to separate JSP code from HTML:

  1. Call external methods
  2. Use the JSP BEAN tag
  3. Use Callpage
Calling external methods is simple and direct, just put the majority of the Java code into a separate .class file and call it. This allows good separation of Java and HTML. The external methods are loosely coupled to the JSP. For example:
<TD>
<%
    ContentGenerator co = new ContentGenerator("15", "phydeaux", 0);
%>
<%= co.getHTML() %>
</TD>

Use of the JSP BEAN tag has all the advantages of calling external methods plus the added advantage of adding structure to the relationship between the Java bean and the JSP. The BEAN tag lends itself better to tooling than the first method mentioned above because the BEAN tag is an HTML construct with strict syntax.

Here is an example of using the BEAN tag.

<TD>
<BEAN varname="cgb"
    type ="com.ibm.ContentGenBean"
    introspect="yes"
    beanName="com.ibm.ContentGenBean">
</BEAN>
<%= cgb.getHTML() %>
</TD>

The above methods restrict you to Java. Use of Callpage allows you to load a separate JSP. This method lends itself to more course grained applications where the grain size is a JSP.

Here is an example of using Callpage.

<%
    com.sun.server.http.HttpServiceResponse httpServiceResponse =
        (com.sun.server.http.HttpServiceResponse) response;
%>
...
<TD>
<%
    httpServiceResponse.callPage("/freeside/c_fromAccount.jsp", request);
%>
</TD>

Business Logic

The business logic part of an interaction is isolated from the details of Web technology. As a result, it is valuable to consider the interface between the Web parts of the interaction (interaction controllers and UI logic) and the business logic.

The business logic part of a Web application is the piece of code ultimately responsible for satisfying client requests. As a result, business logic must address a wide range of potential requirements which include ensuring transactional integrity of application components, maintaining and quickly accessing application data, supporting the coordination of business workflow processes, and integrating new application components with existing applications. To address these requirements and help facilitate the development of business logic on the Web application server, the Framework provides the following core services:

A detailed discussion of the core Framework services is beyond the scope of this paper. A detailed discussion of the Framework services can be found at http://www.ibm.com/developer/features/framework/framework.html.

Separation of UI and Business Logic

Command beans provide a standard way to invoke a business logic request using a single round-trip message. A command bean is a JavaBean that encapsulates a single request to a target server (i.e., the server where the command is to be executed). The target server can be the same JVM as the client or a separate JVM.

The command bean infrastructure allows a command to be executed within the environment of a target server, so that multiple accesses by the command to server resources avoids distributed overhead. Any server can be a target if it supports Java access to its resources and provides a protocol to copy the command bean between a Web application JVM and the command server JVM.

Command beans allow the server side of the Web application to be partitioned into efficient units of interaction. The Web application parts (i.e. interaction controller and UI logic) are independent of the style of the command bean's implementation and independent of where the command bean is physically executed.

The figure titled "Command Bean Infrastructure" shows the internal components that comprise the command bean execution environment. Command beans that execute locally (i.e. in the same JVM as the Web application) simply implement the Command interface. If a command bean is to execute remotely on another server it implements the TargetableCommand interface which is an extension of the Command interface that allows for remote execution; this is done by extending the TagetableCommandImpl class. Regardless of whether the command bean executes locally or remotely the JSP/servlet executes the command bean in the same way.

The steps in a command bean's execution are:

  1. The JSP/servlet instantiates the command bean (detailed discussion of command bean instantiation to follow.) It then sets the command bean's input properties. Finally, the JSP/servlet calls the perform method on the command bean.
    If the command bean executes locally skip to step 2 below. Otherwise, these additional steps occur:
  2. The perform method, if successful, returns a copy of the command bean with its output properties set to the results of the underlying business logic task.
  3. Control flows to the JSP/Servlet which is now free to query the output properties of the command bean.

The following sections describe in detail command instantiation, the command bean interface and the relationship between command beans and EJB.

Instantiating a Command Bean

There are several ways to instantiate a command bean:
        MyCommand myCommand = new MyCommand();
        MyCommand myCommand =
            (MyCommand) Beans.instantiate(null, beanName);
where the beanName is either a class or instance name.
        MyCommand myCommand = (MyCommand) factory.create(...);
where parameters can be used to determine the class or bean name.

Because these different ways to instantiate each have advantages that fit different scenarios, command beans do not specify how it must be done.

The Command Bean Interface

The command bean interface (see Listing 7) provides the set of methods common to all commands that the Web application uses to control the life cycle of a command bean. Input and output data for a command are passed via JavaBean properties. The following describes these methods:

        public void setXXX(XXX xxx);
These methods are not part of the command bean interface because they are different for each command class.
        public boolean isReadyToCallPerform();
This method is part of the command bean interface.
        public void perform() throws CommandException;
The perform method will not work until all of the required input properties have been set (i.e., it is in the "initialized" state.) This method moves the command from the initialized state to the "executed" state. This method is part of the command bean interface.
        public YYY getYYY();
These methods will not work until the perform method has been called (i.e., it is in the "executed" state). These methods are not part of the command bean interface because they are different for each command class.
        public void reset();
This resets the output properties to the values they had prior to the perform method being called (e.g., null or 0). This method is part of the command bean interface.

Relationship of Command Beans and EJB

An obvious question is why not use IIOP to SessionBeans to accomplish the same objective as commands. The answer is that commands have the following advantages:

The overhead of 1 and 2 can often be done once for many SessionBean instances. However, there are still three round-trip messages required per instance.

On the other hand, command beans provide an EJBCommandTarget shown in Listing 8 using a CommandServerEntityBean shown in Listing 9. An EntityBean is used instead of a SessionBean so many different transactions can access the same instance and this instance has the only distributed object stub required in the Web application JVM. This instance is gotten once at server startup and subsequently cached inside EJBCommandTarget. This allows each logical request to the EJB server to cost only a single message, because the overhead in steps 1, 2, 3 and 5 above are factored out and done only once, which amortizes their cost over many command bean executions.

The CommandTarget extends java.rmi.Remote, so that it can potentially be an EJBObject (either SessionBean or EntityBean). This allows the case where the TargetableCommand.setCommandTarget parameter is an EJB.

Command Beans using EJBs

The business logic of a Web application often accesses data in a database. EJB EntityBeans are a convenient way to wrap the relational database layer in an object layer, hiding the complexity of database access. Because a single business task may involve accessing several tables in a database, modeling rows in those tables with EntityBeans makes it easier for command beans to manipulate the data. The Freeside banking demo has several database tables representing such data as accounts, customers, funds transfers, etc. Each table is represented by an EJB EntityBean. The code in Listing 10 implements the AccountBean.

The AccountBean uses a convenience object called a databean. The databean is a JavaBean used to create a non-transactional copy of the data of the EntityBean which owns it. The code in Listing 11 implements the AccountDataBean. Command beans using the AccountBean, such as the ViewAccounts command bean in Listing 6, will actually retrieve output data as AccountDataBean objects.


Summary

This paper has addressed a wide variety of client and server technologies related to creating an e-business application. A couple of factors bare repeating here:

With the above two design concepts and a better understanding of the technology choices for e-business application development you can use the IBM Application Framework for e-business to your best advantage.


References

  1. IBM Application Framework for e-business - Web Application Programming Model
  2. Developing Dynamic Web Sites Using the WebSphere Application Server

Appendix A - General Web Page Design Guidelines

While website and Web application design is a highly volatile and personal topic, below are presented some general guidelines. Special circumstances may justify breaking some of these "rules".


Notes

Session object: A session is a series of requests originating from the same user, at the same browser. The Web server can maintain state information about sessions. The session state is accessed through a session object.

Use the getSession method of the HttpServletRequest object to obtain a session. When you first obtain the HttpSession object, a unique session ID is created and typically sent back to the browser as a cookie. Each subsequent request from this user (at the same browser) passes the cookie. The session ID is used to find the user's existing HttpSession object.

After a session is established, you can add and retrieve user-defined data to the session. The HttpSession object has methods similar to those in java.util.Dictionary for adding, retrieving, and removing arbitrary Java objects.
[Back]

Enterprise JavaBeans (EJB): EJBs are distinguished from JavaBeans in that they are non-visual, designed to be installed on a server, and accessed remotely by a client. EJBs have a deployment descriptor (similar to JavaBeans properties). The deployment descriptor includes the primary key of the EJB (entity Beans only), the home interface and the remote interface.

There are two types of Enterprise JavaBeans:

A typical session Bean has the following characteristics:

A typical entity Bean has the following characteristics:

Typically an entity Bean is used for information that has to survive system crashes, while in session Beans, the data is transient and does not survive when the client's browser is closed. For example, a shopping cart contains information that may be discarded uses a session Bean, and an invoice issued after the purchase of the items is an entity Bean. One other difference is that an entity Bean very often makes direct calls on a database.

To learn more about Enterprise JavaBeans visit http://www.javasoft.com/products/ejb/index.html.
[Back]


Listings


Listing 1 - Detecting browser information
    //Create browser object
    var browser = new Object();

    //Determine browser major version
    browser.version = parseInt(navigator.appVersion);

    //Determine if running Netscape or IE
    browser.isNetscape = false;
    browser.isIE = false;
    if (navigator.appName.indexOf("Netscape") != -1)
        browser.isNetscape = true;
    else if (navigator.appName.indexOf("Microsoft") != -1)
        browser.isIE = true;
[Back]
Listing 2 - Request validation using JavaScript
<script>

// verifyInput is a convenience function that consolidates 
// inputs and delegates to helper functions.
function verifyInput(amount, toAccountObject, fromObject) {
    return verifyAmountInput(amount) &&
           verifyAccountSelection(toAccountObject, fromObject);
}

// verifyAmount determines if the transfer amount is a valid 
// positive number.
function verifyAmountInput(amount ) {
    var newAmount = parseFloat(amount);
    if (newAmount > 0 && newAmount == amount) {
        return true;
    }
    alert("The number " + amount + " your entered is not a " +
          "valid amount! \nPlease enter a positive number! ");
    return false;
}

// verifyAccountSelection finds the selected accounts and 
// ensures that to and from are different.
function verifyAccountSelection(toAccountObject,
                                fromAccountObject) {
    var to_account = "";
    var from_account = "";
    for (var i = 0; i < toAccountObject.options.length; i++) {
        if (toAccountObject.options[i].selected) {
            to_account = toAccountObject.options[i].value;
        }
    }
    for (var i = 0; i < fromAccountObject.options.length; i++) {
        if (fromAccountObject.options[i].selected) {
            from_account = fromAccountObject.options[i].value;
        }
    }
    if (to_account == from_account) {
        alert(" Please check your accounts selection! " +
              "\nMake sure they are not the same account!" );
        return false;
    }
    return true;
}
</script>
[Back]
Listing 3 - "Roll your own" privilege verification
<%

    // try to get the session object from the request object
    HttpSession session = request.getSession(false);

    // construct a partial URL
    String urlString = JSPUtil.getPreferredHttpScheme() + "://" + 
        request.getServerName() + "/freeside/"; 

    // if there is no session or the session is new
    // route the user to the login screen
    if (session == null || session.isNew()) {
        response.sendRedirect(urlString + "login.jsp");
        return;
    }

    // try to get the user authentication info from the session
    CustomerDataBean customerInfo =
        (CustomerDataBean) session.getValue("customer");

    // a null customerInfo indicates the user is not authenticated
    // route the user to the login screen
    if (customerInfo == null) {
        response.sendRedirect(urlString + "login.jsp");
        return; 
    }
%>
[Back]
Listing 4 - Mapping user input to a command bean property
<%
    // instantiate a viewAccounts command bean
    ViewAccounts viewAccountsCommand = new ViewAccounts();

    // assume authentication is complete, retrieve the user ID
    // and set the CustomerID property
    viewAccountsCommand.setCustomerID(customerInfo.getID());

    // ask the command manager to execute the command.
    try {
        viewAccountsCommand = (ViewAccounts)
            viewAccountsCommand.perform();

    } catch (Throwable e) {
        out.println("<PRE>");
        e.printStackTrace(out);
        out.println("</PRE>");
    }
%>
[Back]
Listing 5 - Invoking UI logic with sendRedirect
<%
    int transferFrom = -1;
    int transferTo = -1;
    double amount = 0.00;
    
    try {
        String transferFromString = request.getParameter("transferFrom");
        String transferToString = request.getParameter("transferTo");
        String amountString = request.getParameter("amount");

        // here is an example of input validation done in Java
        if (transferFromString == null ||
            transferToString == null ||
            amountString == null) {
            
            // invalid input, display the account balance page
            response.sendRedirect(urlString + "viewBalance.jsp?");
            return;
        }

        // retrieve the request data 
        transferFrom = Integer.parseInt(transferFromString);
        transferTo = Integer.parseInt(transferToString);
        amount = Double.valueOf(amountString).doubleValue();

        TransferFunds command = new TransferFunds();

        // set the command properties from the request data
        command.setDepositToAccountID(transferTo);
        command.setWithdrawalFromAccountID(transferFrom);
        command.setAmountToTransfer(amount);

        // ask the command manager to execute the command.
        command = (TransferFunds) command.perform();

        } catch (CommandException e) {
            e.printStackTrace();
            String errorMessage = 
                "Sorry! Insufficient funds transfer! " + " Please try again!";
      
            // transfer failed, re-display transfer page
            response.sendRedirect(urlString + "transfer.jsp?errorMessage=" +
                              URLEncoder.encode(errorMessage));
            return;
        }

    String successMessage= "Your funds transfer has been posted!";   

    // transfer succeeded, show account balance page with success message
    response.sendRedirect(urlString + "viewBalance.jsp?successMessage=" + 
                          URLEncoder.encode(successMessage));

%>
[Back]
Listing 6 - Generating HTML from command bean output
<%

    // create the view account command bean and set the input property
    ViewAccounts viewAccounts = new ViewAccounts();
    viewAccounts.setCustomerID(customerInfo.getID());

    try {
        // ask the command manager to execute the command.
        viewAccounts = (ViewAccounts) viewAccounts.perfrom();
        // populate the accounts array from the Accounts output property
        AccountDataBean[] accounts = viewAccounts.getAccounts();
%>

<TABLE  cellspacing=3 cellpadding=0 border=0 >
     <TR>
     <TD align=right><img SRC="/old?u=http%3A%2F%2Fwww-4.ibm.com%2Fsoftware%2Febusiness%2Fbuildapps%2Fimages%2Fimages%2Fl_account.jpg&y=1999" border=0 alt="Account">
     </TD>

     <TD><img SRC="/old?u=http%3A%2F%2Fwww-4.ibm.com%2Fsoftware%2Febusiness%2Fbuildapps%2Fimages%2Fimages%2Femp.gif&y=1999" width=8 height=1 alt="">
     </TD>

     <TD align=right><img SRC="/old?u=http%3A%2F%2Fwww-4.ibm.com%2Fsoftware%2Febusiness%2Fbuildapps%2Fimages%2Fimages%2Fl_balance.jpg&y=1999" border=0 alt="Balance">
     </TD>

     <TD><img SRC="/old?u=http%3A%2F%2Fwww-4.ibm.com%2Fsoftware%2Febusiness%2Fbuildapps%2Fimages%2Fimages%2Femp.gif&y=1999" width=8 height=1 alt="">
     </TD>

     </TR>

<%
        FieldPosition fieldPosition = new FieldPosition(0);
        NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.US);

        // loop through the account information displaying properly
        // formatted data. Note that the table row tags are part of
        // the loop construct dynamically generating the results table.
        for (int i = 0; i < accounts.length; i ++) {
            AccountDataBean account = accounts[i];
            double balance = account.getBalance();
            String formattedBalance =
                currencyFormat.format(balance, 
                                      new StringBuffer(),
                                      fieldPosition).toString();
%>

    <TR>         
    <TD align=center bgcolor="#666666">
       <FONT face="sans-serif"><%= account.getDescription() %></FONT></TD>

    <TD><img SRC="/old?u=http%3A%2F%2Fwww-4.ibm.com%2Fsoftware%2Febusiness%2Fbuildapps%2Fimages%2Fimages%2Femp.gif&y=1999" width=8 height=1 alt=""></TD>

    <TD align=right bgcolor="#666666">
    <FONT face="sans-serif"><%= formattedBalance %></FONT>
    </TD>

    <TD><img SRC="/old?u=http%3A%2F%2Fwww-4.ibm.com%2Fsoftware%2Febusiness%2Fbuildapps%2Fimages%2Fimages%2Femp.gif&y=1999" width=8 height=1 alt=""></TD>


    </TR>

<%
        }
    } catch (Throwable e) {
        e.printStackTrace();
    }
%>
</TABLE>
[Back]
Listing 7 - Command interface

package com.ibm.util.command;

import java.io.*;

/**
 * A command encapsulate a business logic task. 
 * This Command interface provides the client interface for the 
 * most generic form of command, which is the contract between the command
 * client and the command implementation. 
 * The TargetableCommand and CompensatableCommand interfaces offer 
 * additional features. 
 * The TargetableCommandImpl abstract class provides a runtime
 * for command execution, as well as the contract 
 * between the command runtime and the command writer. 
 * <p>
 * Commands provide the following advantages over conventional 
 * client-server interaction: 
 * <ul>
 * <li>They provide a simple uniform way to call business logic,
 *     regardless of the programming style used for the business logic
 *     (eg, EJB, JDBC, stored procedures, connectors, file access).
 * <li>They reduce the number of messages when a client interacts 
 *     with a remote server, often replacing several messages that
 *     do small pieces of work with a single message that does all 
 *     of them. 
 * <li>They provide local-remote transparency (ie, the command client
 *     code is independent of whether the command is executed in the
 *     client's JVM or a remote JVM). 
 * </ul>
 * 
 * A Command has the following states during its lifecycle:
 * <ul>
 * <li><b>New</b>: Just after the command has been created (via a new, 
 *     a factory create, Beans.instantiate, etc.).
 *     In this state the isReadyToCallPerform method should return false
 *     and the get methods should not be called. 
 * <li><b>Initialized</b>: Just after all required input properties have 
 *     been set.  
 *     In this state the isReadyToCallPerform method should return true
 *     and the get methods should not be called. 
 * <li><b>Executed</b>: Just after the perform method has been called. 
 *     In this state the isReadyToCallPerform method should return true
 *     and the get methods should work.  
 * </ul>
 * The only enforcement of these states is that the 
 * TargetableCommandImpl's implementation of the perform method calls 
 * the command's isReadyToCallPerform method prior to executing the command.
 * In this case, if isReadyToCallPerform returns false then an 
 * UnsetInputPropertiesException is thrown.
 * Any other enforcement of these states is up to the command writer. 
 */
public interface Command 
extends Serializable 
{
    /** 
     * Performs the task encapsulated by this command. 
     * This moves the command from the initialized to the executed state.
     * If the isReadyToCallPerform method returns false, 
     * this throws an UnsetInputPropertiesException. 
     * 
     * @exception CommandException The superclass for all command exceptions. 
     */
    public void 
    perform() 
         throws CommandException;

    /** 
     * This allows the command client and the command runtime to ask 
     * the command whether all required input properties has been set.
     * It is called in the client JVM prior to execution being given
     * to the CommandTarget for execution.
     * 
     * @return True if the command is in the initialized or executed state. 
     */
    public boolean
    isReadyToCallPerform();

    /** 
     * This resets the output properties to the values they had
     * prior to calling the perform method, so that the get methods
     * no longer work but the isReadyToCallPerform returns true. 
     * It provides a convenient and efficient way to reuse the same
     * command instance with changes in some input properties or in
     * the CommandTarget. 
     */
    public void 
    reset(); 
}
[Back]
Listing 8 - EJB CommandTarget

package com.ibm.util.command.ejb;


import java.io.*;
import java.rmi.*;
import java.util.*;
import javax.naming.*;
import com.ibm.util.command.*;


/**
 * This is the CommandTarget for commands that are executed in an
 * EJB server.  
 * It uses a server-side EntityBean to allow concurrent access 
 * by different transactions to execute the command on the server. 
 */
public class EJBCommandTarget
implements CommandTarget, Serializable
{
    /**
     * The client-side RMI/IIOP stub for the server-side EntityBean
     * that executes the command on the server. 
     */
    protected CommandServerEntity commandServerEntity = null;

    /**
     * This implements method in the CommandTarget interface. 
     * 
     * @param command The TargetableCommand to be executed.
     * @return The TargetableCommand that has been executed. 
     * If the command.hasOutputProperties returns false,
     * this is allowed to be null as a performance optimization. 
     * @exception RemoteException The superclass for all remove exceptions.
     * This is thrown to allow the possibility for this method to 
     * be an RMI remote method.  
     * An example of this is the com.ibm.util.command.ejb.EJBCommandTarget.
     * @exception CommandException The superclass for all command exceptions.
     */
    public TargetableCommand
    executeCommand(TargetableCommand command)
         throws RemoteException, CommandException
    {
        try {    
            if (commandServerEntity == null) {
                initializeCommandServerEntity();
            }
            return commandServerEntity.executeCommand(command);

        } catch (CommandException ex) {
            throw ex;
        } catch(Exception ex) {
            ex.printStackTrace(); 

            //should I do the user a favor and unwrapper 
            //anything wrapped by a RemoteException?
            throw new CommandException(ex);          
        }       
    }

    /**
     * This creates the single EntityBean on the server,
     * gets its client-side RMI/IIOP stub and caches it
     * in the commandServerEntity instance variable. 
     */
    protected void
    initializeCommandServerEntity()
    {
        try {
            InitialContext initialContext = new InitialContext();

            CommandServerEntityHome commandServerEntityHome = 
                (CommandServerEntityHome)
                IBMJavaOrbRemoteObject.narrow(
                    initialContext.lookup("CommandServerEntityHome"),
                    CommandServerEntityHome.class);
            
            commandServerEntity = commandServerEntityHome.create();

        } catch (Throwable ex) {
            ex.printStackTrace();
            throw new IllegalStateException
                ("Initialization of CommandServerEntity failed.  " +
                 "Is the Transarc container running?");
        }
    }
}
[Back]
Listing 9 - Command Server EntityBean

package com.ibm.util.command.ejb;


import java.io.*;
import java.rmi.*;
import java.util.*;
import javax.ejb.*;
import javax.naming.*;
import com.ibm.util.command.*;


/**
 * This is the server-side EntityBean. 
 * <p>
 * This object has no state.  
 * The EJSPersister is overwritten not to read/write from/to the database.
 */
public class CommandServerEntityBean 
implements EntityBean, CommandTarget
{
    public static int COUNT = 0;
    public int dummy = 0;

    /**
     * This implements the method in the CommandTarget interface.
     * 
     * @param command The TargetableCommand to be executed.
     * @return The TargetableCommand that has been executed. 
     * If the command's hasOutputProperties method returns false,
     * this returns null to avoid an unnecessary copy across the wire. 
     * @exception RemoteException The superclass for all remote exceptions.
     * This is thrown to allow the possibility for this method to 
     * be an RMI remote method (eg, an EJB server).  
     * An example of this is the com.ibm.util.command.ejb.EJBCommandTarget.
     * @exception CommandException The superclass for all command exceptions.
     */
    public TargetableCommand
    executeCommand(TargetableCommand command)
         throws RemoteException, CommandException
    {
        try {
            command.executePerform();
        } catch (CommandException ex) {
            ex.printStackTrace();
            throw ex;
        } catch (Exception ex) {
            ex.printStackTrace(); //for trace

            //Avoid wrappering layers upon layers
            if (ex instanceof RemoteException) {
                RemoteException remoteException = (RemoteException) ex;
                if (remoteException.detail != null) {
                    throw new CommandException(remoteException.detail);
                }               
            }
            throw new CommandException(ex);
        }
        if (command.hasOutputProperties()) {
            return command;
        }
        return null;
    }

    /**
     * This implements the method in the EntityBean interface.
     */
    public void
    ejbCreate()
         throws RemoteException, CreateException
    {
        dummy = ++COUNT; //not really EJB legal, but good for now
    }

    /**
     * This implements the method in the EntityBean interface.
     */
    public void
    ejbPostCreate()
         throws RemoteException, CreateException
    {
    }

    /**
     * This implements the method in the EntityBean interface.
     */
    public void
    ejbLoad()
    throws RemoteException
    {
    }

    /**
     * This implements the method in the EntityBean interface.
     */
    public void
    ejbStore()
    throws RemoteException
    {
    }

    /**
     * This implements the method in the EntityBean interface.
     */
    public void
    ejbRemove()
    throws RemoteException, RemoveException
    {
    }

    /**
     * This implements the method in the EntityBean interface.
     */
    public void
    setEntityContext(EntityContext entityContext)
    throws RemoteException
    {
    }

    /**
     * This implements the method in the EntityBean interface.
     */
    public void
    unsetEntityContext()
    throws RemoteException
    {
    }

    /**
     * This implements the method in the EntityBean interface.
     */
    public void 
    ejbActivate()
        throws RemoteException
    {
    }

    /**
     * This implements the method in the EntityBean interface.
     */
    public void 
    ejbPassivate()
        throws RemoteException
    {
    }
}
[Back]
Listing 10 - AccountBean EntityBean

package freeside.beans;

import java.math.*;
import java.rmi.*;
import javax.ejb.*;

public class AccountBean
implements EntityBean
{
    public boolean canWriteChecks = false;
    public double balance = 0.0;
    public String description = null;
    public int customerID = 0;
    public int id = 0;

    public void
    ejbCreate(double balance,
              String description,
              int customerID)
         throws RemoteException, CreateException
    {
        this.canWriteChecks = false;
        this.balance = balance;
        this.description = description;
        this.customerID = customerID;

        this.id = 
            EntityBeanUtility.autoincrement(AccountBean.class);
    }
    
    public void
    ejbPostCreate(double balance,
                  String description,
                  int customerID)
         throws RemoteException, CreateException
    {
    }

    public AccountDataBean
    getDataBean()
         throws RemoteException
    {
        AccountDataBean dataBean = 
             new AccountDataBean(canWriteChecks,
                                 balance,
                                 description,
                                 customerID,
                                 id);

        return dataBean;
    }

    public void
    updateEntityBean(AccountDataBean dataBean)
         throws RemoteException
    {
        this.canWriteChecks = dataBean.getCanWriteChecks();
        this.balance = dataBean.getBalance();
        this.description = dataBean.getDescription();
        this.customerID = dataBean.getCustomerID();
        this.id = dataBean.getID();
    }

    public void
    setBalance(double balance)
        throws RemoteException
    {
        this.balance = balance;
    }
    
    public double
    getBalance()
        throws RemoteException
    {
        return balance;
    }
    
    public void
    setDescription(String description)
        throws RemoteException
    {
        this.description = description;
    }
    
    public String
    getDescription()
        throws RemoteException
    {
        return description;
    }
    
    public void
    setCustomerID(int customerID)
        throws RemoteException
    {
        this.customerID = customerID;
    }
    
    public int
    getCustomerID()
        throws RemoteException
    {
        return customerID;
    }

    public void
    setCanWriteChecks(boolean canWriteChecks)
         throws RemoteException
    {
        this.canWriteChecks = canWriteChecks;
    }
    
    public boolean
    getCanWriteChecks()
         throws RemoteException
    {
        return canWriteChecks;
    }

    //id IS READONLY
    public int
    getID()
        throws RemoteException
    {
        return id;
    }
    
    public void
    ejbLoad()
         throws RemoteException
    {   
    }

    public void
    ejbStore()
         throws RemoteException
    {
    }

    public void 
    setEntityContext(EntityContext entityContext)
        throws RemoteException
    {
    }

    public void 
    unsetEntityContext()
        throws RemoteException
    {
    }   

    public void
    ejbActivate()
         throws RemoteException
    {
    }

    public void
    ejbPassivate()
         throws RemoteException
    {
    }

    public void
    ejbRemove()
         throws RemoteException, RemoveException
    {
    }
}
[Back]
Listing 11 - AccountDataBean JavaBean

package freeside.beans;

import java.math.*;
import java.rmi.*;
import java.sql.*;
import javax.ejb.*;

public class AccountDataBean
implements java.io.Serializable
{
    public boolean canWriteChecks = false;    
    protected double balance = 0.0;
    protected String description = null;
    protected int customerID = 0;
    protected int id = 0;

    public
    AccountDataBean()
    {
    }

    public 
    AccountDataBean(boolean canWriteChecks,
                    double balance,
                    String description,
                    int customerID,
                    int id)
    {
        this.canWriteChecks = canWriteChecks;
        this.balance = balance;
        this.description = description;
        this.customerID = customerID;
        this.id = id;     
    }

    public void
    readResultSet(ResultSet resultSet)
         throws SQLException
    {
        canWriteChecks = (resultSet.getInt(1) == 1);
        balance = resultSet.getDouble(2);
        description = resultSet.getString(3);
        customerID = resultSet.getInt(4);
        id = resultSet.getInt(5);
    }

    public void
    setCanWriteChecks(boolean canWriteChecks)
    {
        this.canWriteChecks = canWriteChecks;
    }

    public boolean
    getCanWriteChecks()
    {
        return canWriteChecks;
    }
        
    public void
    setBalance(double balance)
    {
        this.balance = balance;
    }
    
    public double
    getBalance()
    {
        return balance;
    }
    
    public void
    setDescription(String description)
    {
        this.description = description;
    }
    
    public String
    getDescription()
    {
        return description;
    }
    
    public void
    setCustomerID(int customerID)
    {
        this.customerID = customerID;
    }
    
    public int
    getCustomerID()
    {
        return customerID;
    }
    
    public void
    setID(int id)
    {
        this.id = id;
    }
    
    public int
    getID()
    {
        return id;
    }
}
[Back]
Privacy Legal Contact