ead4j.jade application developer handbook v2.6

72
Jade Framework Developer’s Handbook Tuesday, February 05, 2002 IBM Confidential 1 Enterprise Application Development frameworks for Java Jade Framework Application Developer’s Handbook Version 2.5.4 Prepared by: EAD National Practice IBM CONFIDENTIAL © Copyright 2000 by International Business Machines Corporation All rights reserved

Upload: joyfulselva

Post on 18-Nov-2014

2.360 views

Category:

Documents


42 download

TRANSCRIPT

Page 1: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 1

Enterprise Application Development frameworks for Java Jade Framework Application Developer’s Handbook Version 2.5.4 Prepared by: EAD National Practice

IBM CONFIDENTIAL © Copyright 2000 by International Business Machines Corporation

All rights reserved

Page 2: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 2

Table of Contents

• 1. Document History 4 1.1 DOCUMENT SCOPE 5 1.2 APIS SUPPORTED 5

• 2. Jade Framework Details 5 2.1 OVERVIEW 5 2.2 COMPONENT MODEL 5

2.2.1 JavaServer Pages (JSP) 6 2.2.2 Servlet 6 2.2.3 Parameters Object 6 2.2.4 Domain Object 7 2.2.5 Process Object 7 2.2.6 View Bean 7 2.2.7 Message Bean 8 2.2.8 State Bean 8 2.2.9 ResultHandler 8 2.2.10 Result Bean 8 2.2.11 ApplicationContext 9 2.2.12 ConfigContext 9 2.2.13 ActionHandlerContext 10 2.2.14 ActionHandler 10 2.2.15 I18NContext 10 2.2.16 JadeSession 10 2.2.17 LogContext 10

2.3 COMPONENT COLLABORATION 12 2.4 JADE PACKAGE STRUCTURE 13 2.5 JADE CLASSES AND INTERFACES 14

2.5.1 JSP Classes 14 2.5.2 Servlet Classes 16 2.5.3 Configuration Classes and Interfaces 18 2.5.4 ActionHandler Classes and Interfaces 20 2.5.5 Bean Classes and Interfaces 21 2.5.6 Exception Classes 22 2.5.7 Session Classes and Interfaces 23 2.5.8 Utility Classes and Interfaces 24

2.6 JADE RESOURCES 24 2.6.1 ead4j_jade_bootstrap.properties 25 2.6.2 actionHandler.xml 27 2.6.3 i18n 27 2.6.4 application.xml 27 2.6.5 device.xml 27 2.6.6 html.xml 28 2.6.7 mapping.xml 28 2.6.8 message.xml 28 2.6.9 property.xml 28

2.7 APPLICATION CONFIGURATION WITH JADE 31 2.7.1 actionHandler.xml 31 2.7.2 ActionHandler file modifications 31 2.7.3 i18n 32 2.7.4 device.xml 32 2.7.5 html.xml 32 2.7.6 mapping.xml 33 2.7.7 message.xml 35

Page 3: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 3

2.7.8 property.xml 36 2.8 JADE PROGRAMMING MODELS 37

2.8.1 Single Servlets or Multiple Servlets 37 2.8.2 Flow of Control – Single Servlet Model 37 2.8.3 Flow of Control – Multiple Servlets Model 41

• 3. Designing EAD4J Jade Applications 41 3.1 CREATING JSPS 41 3.2 CREATING SERVLETS 41 3.3 CREATING/USING PARAMETERS 42 3.4 CREATING/USING JADESESSION 43 3.5 CREATING ACTIONHANDLERS 44

3.5.1 Shallow & Deep ActionHandlers 45 3.6 CREATING STATE BEANS 46

3.6.1 Defining a state for every user interaction 47 3.7 CREATING VIEW BEANS 47

3.7.1 Implementing the ModelCrawler interface 49 3.8 CREATING MESSAGE BEANS 50

3.8.1 Messages in the Process Object Layer 50 3.8.2 Messages in the View Bean Layer 51 3.8.3 Messages in the ActionHandler Layer 51 3.8.4 Messages in the Servlet Layer 52 3.8.5 Multiple Messages 52 3.8.6 Pre-defined Messages 52

3.9 WORKING WITH THE RESULTHANDLER 55 3.9.1 Storing Data in Session with ResultHandler 55 3.9.2 Storing Data in Session with a sub-class of ResultHandler 58 3.9.3 UNDO 59

3.10 CREATING PROCESS OBJECTS 61 3.10.1 Transaction considerations 61

3.11 HANDLING EXCEPTIONS 62 3.11.1 ActionHandler Level Exception Handling 63 3.11.2 Servlet Level Exception Handling 63 3.11.3 JSP Level Exception Handling 64

3.12 LOGGING 64 3.12.1 Simple Logging 64 3.12.2 Logging with Log4J 64

• 4. Appendix – Utility Descriptions 65 4.1 EMAIL 65

4.1.1 Classes and mailConfig.xml File Description 65 4.1.2 Class Diagram 68 4.1.3 Implementation Recommendations 68 4.1.4 Reinitializing the EmailSenderFactory 71

4.2 MULTIPARTREADER UPDATED CLASSES 71 4.2.1 MultipartReader Classes 71 4.2.2 MultipartReader methods: 71 4.2.3 HTML for the Upload Process 72 4.2.4 JADE Upload Process 72 4.2.5 Upload Security 72

Page 4: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 4

1. Document History Version Date Description Authors

0.1 draft 2000.Dec.20 Initial draft Sidhartha Kaw, Robert Zuidema

0.2 draft 2001.Jan.04 Updated – some details of framework and HBA application

Sidhartha Kaw, Robert Zuidema

0.3 draft 2001.Jan.09 Updated – details of environment setup, HBA use cases

Sidhartha Kaw, Robert Zuidema

0.4 draft 2001.Jan.19 Updated – cookbook details, log4j configuration Sidhartha Kaw, Robert Zuidema

0.5 draft 2001.Feb.06 Updated – ActionHandlers, view beans Sidhartha Kaw, Robert Zuidema

0.6 draft 2001.Feb.07 Updated – resource configuration details Sidhartha Kaw, Robert Zuidema

0.7 draft 2001.Feb.08 Updated – WebSphere Deployment information Sidhartha Kaw, Robert Zuidema

0.8 draft 2001.Feb.12 Updated – Jade Classes and Interfaces Sidhartha Kaw, Robert Zuidema

0.9 draft 2001.Feb.15 Updated – Exception Handling, Logging Sidhartha Kaw, Robert Zuidema

0.10 draft

2001.Apr.20 Updated – JSP delegation, Richard Hom

1.0 draft 2001.May.13 Updated for V2 Sidhartha Kaw

2.0.2 2001.June.29 Updated Video Store application documentation Sergio da Silva

2.1.0 2001.July.26 Updated with changes for 2.1.0 Sidhartha Kaw

2.1.0 2001.Aug.01 Final verification and validation Sidhartha Kaw

2.5.0 2001.Aug.16 Split from generic handbook Bob Patten

2.5.4 2001.Oct.24 Updated with Process Contract info Bob Patten

Page 5: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 5

1.1 Document Scope This document describes the details of the EAD4J Jade Framework including information on setting up the development environment and guidelines that should be used when developing an application using the framework.

1.2 APIs Supported At the time of this release, the IBM tools have just started supporting Servlet API 2.2 and JSP API 1.1. Hence the Jade Framework’s support is limited as described below:

• Servlet API 2.1, 2.2

• JSP API 0.91, 1.0, 1.1 (No explicit Tag libraries supported thru the framework at this time)

2. Jade Framework Details

2.1 Overview This section attempts to explain all the details of the Jade Framework from a developer’s point of view. For an architectural overview of Jade, please read the accompanying reference document titled “Jade Architecture and Reference”.

We will begin by discussing the components of the framework and then drill down into the different components to get a better understanding of the rationale behind their design and then look at how all the components work together.

2.2 Component Model Below is high-level diagram of the different components in the Jade Framework:

Page 6: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 6

Client

Base Servlet

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

HTML

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

Java Server Pages (JSPs)

Custom Servlet(s) Gateway Servlet

Application Context

ConfigContext

Cmd/ActionContext

Command

Command

Command

Command

Utility Classes

File SystemProperty/XML Files Log Files

Model

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

Process Objects(business rules)Adaptor Layer

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

Domain Objects(business objects)

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

Middleware (JMS, EJBs, JNDI, JDBC, MQ, etc)

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

Legacy Access

Bootstrap Process

Exceptions

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

HTMLScriptingSS Includes -- (ServletBean result)

JavaScript Edit Check library

log4j customSimple jLog

Log ContextI18NContext

Result Bean State Bean Message Bean View Bean

XMLContext

Result Handler

Session

Figure 1 Components of the Jade Framework

The framework is comprised of many different components. Many of these components can be used outside of the framework itself; however, taken together they provide a solid foundation from which to build an application. Here are the details:

2.2.1 JavaServer Pages (JSP) The JSP is a JavaServer Page that represents the UI portion of the application. It is responsible for the display of the dynamic portion of the UI. It is critical that the JSP does not access the business domain directly but instead has a single interface from which to obtain its data. This interface is the ResultBean.

2.2.2 Servlet The servlet is the interface from the UI (JSPs) to the backend Process Objects. The primary responsibility of the servlet is to identify the correct process object to invoke, and pass any input information to that Process Object if there is any. The servlet should contain no business knowledge and no knowledge of the workflow (UI navigation) of the application. They also manage the “session” of the application.

2.2.3 Parameters Object The Parameters Object is used to insure separation of concerns between the servlet, ActionHandler and Process objects. All HTTP input data is encapsulated within the Parameters object such as headers, cookies, form data etc; therefore, only objects from the servlet “up” (JSP, Servlet, etc) know about HTTP. Other layers/objects do not know where the input comes from. The Parameters object can also be used as a data container as is used in the ResultHandler to store values that need to sent to the ViewBean.

Page 7: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 7

2.2.4 Domain Object Domain objects are standalone entities that represent aspects of the domain or business. They may be as simple as a Person object or an Address object and as complex as an Order object (which may contain multiple Order Line Item objects). These objects may be developed as part of application development or obtained from a 3rd party source. Regardless, these objects are standalone entities that represent different parts of the business.

2.2.5 Process Object Process Objects are responsible for the business policy rules. It is these rules, more than specific domain objects, which define how an application operates. A Process Object may interface or access several Domain Objects in order to perform or fulfill a specific business request (e.g.: user request to perform a business function). A Process Object may use Domain Objects specific to a business or generic ones obtained from a 3rd party source. Regardless, the Process Object defines the processing rules for an application or business. Another term often used for Process Objects is “business controllers” where the controllers are responsible for manipulating several Domain Objects in order to complete a specific task. This helps to keep the Domain Objects pure and they can be developed as true standalone components without being tied specifically to how they are being used for the particular application being developed. This allows the same set of Domain Objects to be used across multiple applications with different Process Objects being developed for the different applications to talk to the Domain Objects.

2.2.6 View Bean The View Bean is a flat representation of non-persistent business objects that can be used in multiple UI implementations.

In the case of JSPs the View Bean is responsible for providing a single point of access to all the application specific dynamic content needed to display on the given page. The JSP does not directly access any other object; instead it goes through the View Bean for all information. Thus the View Bean acts as a facade for the JSP as it hides the fact that the View Bean may have been created using several Domain Objects.

In addition, the View Bean is responsible for the formatting of data that is represented on the JSP. For example, on one page the value 1000 may be displayed as the numeric value 1000 and on another page (another view) this same value may be displayed as $1000.00. The View Bean may access formatters (or other objects) or may perform this formatting directly. Another example is the fact that attributes that represent money such as amounts are often represented with Java types such as BigDecimal or float or double in the Domain Object. It would be the View Bean’s responsibility to convert the amount attribute of the Domain Object into its appropriate String representation with any additional formatting that has to be done such as locale specific symbols (like $ or Rs.) and precision formatting etc.

There are two important details to consider regarding the View Beans:

1. The View Bean is an abstract class that must be sub-classed to solve a particular need. The subclass must implement the Model Crawler interface. This interface only defines one method that has the responsibility of getting the Object(s) it needs out of the input Parameters and builds/stores the necessary data for retrieval by the JSP.

2. The View Bean for a specific response is not hard-coded and called directly from within a Process Object. Instead the View Bean is a look-up value in a softly configurable table and it is located dynamically according to the application state (more on this in the State Bean description). This allows the Process Object to handle any type of request, be it from a servlet, from an applet, an application or another type of mechanism.

In the case of JSPs a specific sub-class of View Bean will flatten out the objects that the JSP needs to render the page.

In the case of applets another specific sub-class of View Bean can create a tree of objects to allow the applet to render its panel.

Page 8: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 8

Thus by allowing dynamic look-up of the actual class that implements the View Bean the Process Object logic does not have to change to accommodate different UI implementations.

2.2.7 Message Bean The Message Bean is responsible for providing any messages that the application would like to send to the JSP for display to the end user. When a user performs an operation, the application often needs to inform the user whether or not the operation was successful. The Message Bean is responsible for carrying the message text, along with providing for optional message formatting. Message Beans can contain any number of messages, either stored in order or stored unordered with a key.

2.2.8 State Bean The State Bean represents the application state at the end of a specified process.

The State Bean does not necessarily represent a complex state machine; it merely represents the business state that the application is in. In the current implementation the State Bean is just a wrapper for a string that represents this state.

In order to guarantee the correct separation of responsibilities, the Process Object should not know how to build the Result Bean (and associated classes). However, in a transactional system, live objects can only be accessed inside the context of a transaction, and the transaction context should be in the scope and under the responsibility of the Process Object.

The State Bean allows the Process Object to be independent and to have no knowledge on how to build the Result Bean. For more details check the Result Bean description.

In the case where the client being served is a web browser, the State Bean is responsible for determining the correct View Bean to instantiate and the next JSP to be displayed based on the result of executing a particular task on a Process Object.

The advantage of having this State Bean is two fold:

1. It allows the servlet to be free from having to know specifically which JSP has to be displayed as a result of executing a particular task on a Process Object.

2. It allows the Process Object to focus on the Business Logic and shields it from changes that can happen in the UI layer.

In the case of a non-JSP approach, the look-up from the State Bean could return a specific panel to be displayed in an applet or a frame in an application or even a specific XML encoder to drive a transcoder and also to look-up the specific View Bean that would provide the dynamic data to them.

2.2.9 ResultHandler The ResultHandler is a helper class that is used to isolate the Process Object from the construction of the ResultBean. The ResultHandler is created in the ActionHandler layer and passed into Process Object. The ResultHandler has convenience methods for setting the state, setting a message and adding objects that are still in the transaction context, so that the ResultBean framework can create the view.

2.2.10 Result Bean The Result Bean is a container for the different Objects that can be used to display information about the results of a given Process Object to some UI layer.

It enables the different results to be generically passed from the Process Object layer to the Controller/Servlet layer. The Result Bean contains the following components:

• View Bean – the dynamic data needed to display.

• Message Bean – the messages needed (if any) to display.

Page 9: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 9

• State Bean – the state of the application (used for dynamic look-up).

The main objective of the framework regarding the Result Bean is twofold:

1. Shield the Process Object from knowledge on how to build a Result Bean, so that any changes in UI requirements are not transferred to the Process Object layer.

2. Allow the Process Object to establish and control the transaction context for the application.

In order to meet these two contradicting requirements, the following approach was designed:

The Process Object creates the Result Bean, so that the context of the transaction is maintained, but the method used to create the Result Bean is totally transparent to the Process Object. In other words the Process Object does not “know” how to construct the Result Bean it delegates the construction to the Result Bean.

The Result Bean constructs the correct associated classes (View Bean, Message Bean and State Bean) through the following mechanism:

The Result Bean looks up the class to fulfill the UI requirements of the application in its given state, by looking up a key value pair from a property file, that maps the state the application is in.

After the entry is located, the class is created using reflection.

Once the class is created a specific interface method is invoked, that is able to provide the View Bean with the appropriate data, of course this method is application specific.

2.2.11 ApplicationContext Nearly every application has some set of read-only data that needs to be accessible by all portions of the application. This information is contained in the Application Context that provides a single point of access for the entire application.

2.2.12 ConfigContext The ConfigContext is responsible for loading configuration data for the framework and application. The configuration data can be loaded from the file system using property files, XML files or even from a database.

The ConfigContext is responsible for information pertaining directly to the configuration of the application. Most of this information is obtained from XML files; however, implementations of the interface can be written to load configuration data from a variety of locations. The framework provides the capability to load all properties located in the “property” directory. The framework can be extended to support other data sources. Note: the ConfigContext is never accessed directly – application development accesses this information through the Application Context. Some of the files that get loaded by ConfigContext are:

• application.xml – Specifies the applications that are being supported by a single Jade configuration

• property.xml – Specifies miscellaneous name-value pairs • html.xml – Specifies names of HTML files that are used in the application giving the JSP the

capability to invoke them via a constant rather than by their names.

• device.xml – Specifies the devices that Jade is serving. The default is Standard Browser.

• mapping.xml – Specifies the mapping between the states, views, devices, locales and JSP/HTML.

• message.xml – Specifies the messages used by Jade, defines message types, such as errors and warnings, and defines the types of Message Beans. In versions of Jade prior to 2.6, applications were required to store messages in property files accessed via the I18NContext. As of Jade 2.6, the recommended method to configure messages is in the application’s message.xml file, stored in the application’s property directory.

Page 10: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 10

2.2.13 ActionHandlerContext The ActionHandlerContext is a private member of ApplicationContext and is responsible for loading and storing the ActionHandler objects. All the information regarding ActionHandlers is stored in an “actionHandler.xml” file. ActionHandler objects are stored in the ActionHandlerContext using a unique key for each which is defined in the “actionHandler.xml” file. At runtime, a servlet can query the ActionHandlerContext through the ApplicationContext interface for an ActionHandler, given its unique key and execute a specific operation.

2.2.14 ActionHandler An ActionHandler is responsible for encapsulating a single task that has to be performed by a servlet. Often a servlet may have several responsibilities and ActionHandlers can be used to encapsulate the different tasks. ActionHandlers follow a specific design pattern. Every ActionHandler class implements the ActionHandler interface and provides an implementation for the execute() method defined on that interface.

The ActionHandler is primarily used to identify the Process Object to invoke and in specific which method to invoke on the Process Object. In this way, the ActionHandler layer actually provides a layer of insulation between the HTTP specific servlet layer and the Process Object thus making the Process Object unaware that it is “serving” the web layer.

ActionHandlers are responsible for retrieving any session data that was previously stored in session and adding it to the Parameters object. This is because the Process layer should have NO knowledge of session.

Similarly on the way out from Process layer, the ActionHandler is responsible for adding any data to the session object. The ActionHandler is also responsible for instantiating the ResultHandler utility object and passing it to the Process layer. ActionHandlers can be “shallow” or “deep”. “Shallow” action handlers DO NOT invoke a Process Object. They have enough knowledge to display the next page. “Deep” action handlers invoke the Process Object to get the information needed to create the next page.

2.2.15 I18NContext The I18NContext is a private member of the ApplicationContext that manages properties that need multiple locale support such as currencies. The I18NContext uses ResourceBundles to accomplish this task. As of Jade version 2.6, messages should no longer be listed in properties files but instead should be stored in the application-level message.xml file. However, message support via I18NContext is still supported.

2.2.16 JadeSession The JadeSession interface defines the behavior of a session object and allows Jade to be independent of the session implementation. Implementation classes are provided that integrate the Servlet API HttpSession object and the IBMSession object that comes with WebSphere to JadeSession. From Jade’s perspective, as long as an implementation class satisfies the API, it does not matter what the implementation is.

2.2.17 LogContext The LogContext is responsible for handling all requests for logging that are made by the application. It encapsulates the complexity built into the logging portion of the framework. Most applications need to log for several reasons; for instance, the client may request detail logs of what is being done on their site or the rationale may be for debugging purposes. These logs are usually far different than what WebSphere provides.

The framework provides direct support for several types of logging. The first is a fairly simplistic logging implementation, which can be used for non-production type logging. A second utilizes the Log4j open source logging API. We also provide support for the JLog logging API. It is highly suggested that a production level logging mechanism be used for production.

Page 11: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 11

The framework uses LogContextWriters to perform the actual logging. These “writers” handle the actual output of the message to the log store. The concrete “writer” that the framework uses is defined within a configuration file allowing this to be softly configured.

2.2.17.1 Simple Logging The framework includes a logging feature that provides basic functionality.

Commonly there are a number of different log events that may need to be written. These may range from access notes, to transaction traces, to errors (business and technical) and exceptions. The logging provided, as part of the framework contains:

• Debug/non debug mode. Debug mode will print all output from that point on. Non-debug mode will cache the message for later use. For instance, messages may be cached for some period of time and displayed only when there is an exception.

• Logging Levels. Levels include exception, error, warning, info, and debug. In addition to application specified data, log levels will increase the amount of information produced. The level will be configurable in a properties file.

2.2.17.2 Log4j “Log4j, an open source project managed by Apache, allows developers to control which log statements are output with arbitrary granularity. It's fully configurable at runtime by using external configuration files. Best of all, log4j has a gentle learning curve.”

The framework provides an implementation of the LogContextWriter interface, which uses the Log4j logging package. Use of this “writer”, the default implementation, or a custom one can be defined in configuration files.

2.2.17.3 JLog “JLog, an alphaWorks project, allows developers to control which log statements are output with arbitrary granularity. It's fully configurable at runtime by using external configuration files.

The framework provides an implementation of the LogContextWriter interface, which uses the JLog logging package. Use of this “writer”, the default implementation, or a custom one can be defined in configuration files.

2.2.17.4 Customizable Logging The framework provides the LogContextWriter interface, which can be used to implement, customized logging “writers”.

Page 12: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 12

Figure 2 High Level Overview

2.3 Component Collaboration This is a high-level description of how the different components work together in a J2EE web container environment:

1. Client request sent from browser to server (invocation of Servlet) via an HTML

page or a JSP

2. Servlet calls an ActionHandler to handle the request.

3. ActionHandler creates a ResultHandler and passes the Parameters and

ResultHandler to the Process Object to handle functional request (this is the

business process steps to execute the user's request)

4. The Process Object creates and invokes any necessary Domain Objects. For

instance, it may create a Person object and set the attributes in that object based

on user input. 5. A Persistence Transaction Object may then be called, being passed the

necessary domain objects, so that these objects can be persisted (saved).

NOTE: actual persistent strategies are not discussed in detail in phase I of the framework.

6. The PTO invokes data objects that correspond to domain objects. These objects

are responsible for handling the persistence portion of the request. e.g.: they are

responsible for saving the domain object into the persistence store. That may be

a JDBC call (including connection pooling), a call into legacy CICS, or some

other data store.

Page 13: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 13

7. Based on what the Process Object was expected to perform (simple save or

some business process such as obtaining an account balance) the result is stored

into a Result Bean and returned to the Servlet. In addition, an application state is

also stored. This state will be used to determine the next work flow (e.g.: the

next "page" to display)

8. The Servlet uses the result bean's application state to perform a lookup of what

should happen next. To do this the Servlet performs a lookup, based on the

state, to know which JSP to next invoke. Note: the lookup allows minimal

conditional logic to be required; thereby, keeping the application workflow in

the proper layer (i.e.: the process object; not the servlet)

9. The Servlet then launches the JSP passing the View Bean (which was returned as

part of the Result Bean) as part of the request. The JSP then accesses only the

View Bean to determine and render the dynamic portions of the page. The JSP

may also access the Message Bean stored in the Result Bean to display any

messages. The resulting HTML is then displayed/passed to the client browser.

2.4 Jade Package Structure

The package names for the framework are:

• com.ibm.ead4j.jade.action – Contains Framework ActionHandler classes

• com.ibm.ead4j.jade.bean – Contains Framework Bean classes

• com.ibm.ead4j.jade.common – Contains Framework Common classes

• com.ibm.ead4j.jade.config – Contains Framework Configuration classes

• com.ibm.ead4j.jade.config.builder – Contains Framework Configuration Builder classes

• com.ibm.ead4j.jade.jsp – Contains Framework JSP classes

Page 14: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 14

• com.ibm.ead4j.jade.log – Contains Framework Log classes

• com.ibm.ead4j.jade.servlet – Contains Framework Servlet classes

• com.ibm.ead4j.jade.session - Contains Framework Session classes

• com.ibm.ead4j.jade.util – Contains Framework Utility classes

2.5 Jade Classes and Interfaces

2.5.1 JSP Classes

Page 15: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 15

2.5.1.1 BaseJSP As shown in the figure, BaseJSP inherits from the HttpJspBase class, the JSP super class used by WebSphere, that implements the HttpJspPage interface, a requirement for the super-class of the page compiled JSPs according to the JSP specification. The BaseJSP class provides many convenience methods for shielding the developer from the volatile Servlet and JSP specification. In addition to this, the class provides hooks into the rest of the Jade Framework by providing logging and exception handling methods. To set up your JSPs so that they inherit from the BaseJSP, use the following declaration in all your JSPs:

<%@ page extends = "com.ibm.ead4j.jade.jsp.BaseJSP" errorPage = "<whatever your error page is>" %>

Finally, the BaseJSP also provides some utility methods to assist in JSP development. These methods are listed below:

protected String isChecked(String s1, String s2)

protected String isSelected(String s1, String s2)

These methods are very useful when developing JSP pages on which one has to keep the radio-buttons or check boxes selected by a user if the user returns to the page.

Here’s an example:

<td width="210" class="black1"> Yes <input type="radio" value="True" name="yes_radio"

<%= this.isChecked(“Y”, vBean.getPreference()) %> >

&nbsp;&nbsp;&nbsp;&nbsp; No <input type="radio" value="False" name="no_radio"

<%= this.isChecked(“N”, vBean.getPreference()) %> >

&nbsp; &nbsp;</td>

To understand this piece of HTML intermixed with JSP coding, assume that this page has a View Bean already retrieved from the session or request object and the variable name is vBean. Lets assume that this piece of html was part of a form that stored user preferences. When the form was POSTED to the server, some values were sent over and stored in the appropriate objects on the back end. In this example, a “Y” was sent over for a YES and “N” was sent over for a NO. Now suppose, the user comes back to edit his preferences. We want to make sure that all that he selected is already set in the page. To achieve this we can use the utility methods provided by the BaseJSP to check whether the preference that is stored was a “Y” or a “N” and accordingly the word “checked” would be put as the return value of the method. Thus in the HTML, when the page was displayed, the appropriated button would appear selected. This same principle can be applied to check boxes and lists too.

NOTE: It is NOT required to make your JSPs inherit from the BaseJSP class. Your JSPs will work perfectly fine with Jade even if they do not inherit from the BaseJSP class.

2.5.1.2 JSPHelper The alternative to using BaseJSP is to use JSPHelper. It subclasses the JadeBaseHttpServlet class, which is the super class for the rest of Jade. JSPHelper provides the same methods and functionality as BaseJSP but its reuse mechanism is different. JSPHelper methods are used through delegation instead of inheritance. (For a comprehensive discussion of delegation vs. inheritance see Design Patterns, GoF, 1998, pp. 20-21.) To set up your JSPs so that they delegate to JSPHelper, use the following declaration in all your JSPs:

<% com.ibm.ead4j.jade.jsp.JSPHelper help = com.ibm.ead4j.jade.jsp.JSPHelper.singleton(); %>

Page 16: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 16

Here’s an example of how to use the delegate instance:

<td width="210" class="black1"> Yes <input type="radio" value="True" name="yes_radio"

<%= help.isChecked(“Y”, vBean.getPreference()) %> >

&nbsp;&nbsp;&nbsp;&nbsp; No <input type="radio" value="False" name="no_radio"

<%= help.isChecked(“N”, vBean.getPreference()) %> >

&nbsp; &nbsp;</td>

BaseJSP is a subclass of com.sun.jsp.runtime.HttpJspBase that does not exist on all application servers. JSP servlets must implement the HttpJspPage interface, but may do so through different super classes. Because JSPHelper is not sub classed from HttpBaseJSP, it may be used in a JSP for any application server. Using JSPHelper, you may develop JSPs using WTE and execute on another application server without code changes. You should use JSPHelper whenever application server portability is or may become an issue.

NOTE: It is NOT required to make your JSPs use the JSPHelper class. Your JSPs will work perfectly fine with Jade even if they do not use the JSPHelper class.

2.5.2 Servlet Classes

Page 17: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 17

2.5.2.1 JadeBaseHttpServlet The JadeBaseHttpServlet is an abstract class that inherits from HttpServlet. It provides methods that shield the volatile Servlet API and convenience methods for logging, exception handling, parameter parsing and session management.

2.5.2.2 JadeBaseMultiServlet The JadeBaseMultiServlet is a concrete subclass of JadeBaseHttpServlet primarily to be used when developing applications using the Multiple Servlet Programming Model. Application servlets should subclass this servlet whether they are using ActionHandlers or not. This class provides additional methods for processing the request that comes in using the Jade components and provides the ability to set caching strategies on a page per page basis.

2.5.2.3 JadeGatewayServlet The JadeGatewayServlet is a concrete subclass of JadeBaseHttpServlet primarily to be used when developing applications using the Single Servlet Programming Model. This servlet uses the Jade ActionHandler components to process requests. All requests are handled identically.

2.5.2.4 JadeBootstrapServlet The JadeBootstrapServlet is a concrete subclass of JadeBaseHttpServlet used to bootstrap all the configuration properties of Jade.

2.5.2.5 JadeReSetServlet The JadeReSetServlet is a sub-class of JadeBaseHttpServlet that is responsible for resetting the ApplicationContext singleton so that entries in the XML files can be re-read without having to bring down the application server. Please note that properties that are read in from property files will not be refreshed automatically because the JVM caches properties read using ResourceBundles. Only properties in the XML files will be refreshed.

Page 18: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 18

2.5.3 Configuration Classes and Interfaces

2.5.3.1 ApplicationContext This class is a singleton and represents the “global context” of the framework and application. At runtime, this object is loaded with the softly configurable properties of the framework and application. It also provides convenience methods for exception handling and logging. Currently there is one “context” per JVM, so when using Jade, one has to clone the code on every JVM. In a future release of Jade we plan to migrate the under lying details of this class to JNDI to provide a truly “global context” across JVMs.

2.5.3.2 ConfigContext This class is responsible for loading the softly configurable properties into the ApplicationContext object.

In the future, this will be enhanced to support XML descriptors.

2.5.3.3 I18NContext This class is responsible for retrieving properties that need multiple locale support using ResourceBundles.

2.5.3.4 PropertyFilenameFilter This class helps the ConfigContext to locate the property files in a given directory.

2.5.3.5 LogContext This class is responsible for controlling the logging of the framework and application. It can be configured to use the simple logging system provided by Jade or a more sophisticated logging system like Log4J.

Page 19: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 19

2.5.3.6 LogContextWriter This interface defines the methods that a LogContextWriter must support for logging.

2.5.3.7 LogContextWriterLog4J This class provides the implementation of LogContextWriter for Log4J.

2.5.3.8 LogContextWriterJlog This class provides the implementation of LogContextWriter for JLog.

2.5.3.9 LogContextWriterDefault This class provides the implementation of LogContextWriter for the Simple Logging.

2.5.3.10 BootstrapKeys This interface defines the constants for the properties defined in ead4j_jade_bootstrap.properties.

2.5.3.11 ActionHandlerKeys This interface defines the constants for the properties defined in the actionHandler.xml file

2.5.3.12 DatabaseKeys This interface defines the constants for the properties defined in property.xml file.

2.5.3.13 FrameworkKeys This interface defines the constants for the properties defined in the property.xml file

2.5.3.14 HTMLKeys This interface defines the constants for the properties defined in the html.xml file

2.5.3.15 JSPKeys This interface defines the constants for the properties defined in the property.xml file

2.5.3.16 LogKeys This interface defines the constants for the properties defined in the ead4j_jade_bootstrap.properties file

2.5.3.17 MessageKeys This interface defines the constants for the properties defined in the Jade message.xml file.

2.5.3.18 StateKeys This interface defines the constants for the properties defined in the mapping.xml file

2.5.3.19 ViewKeys This interface defines the constants for the properties defined in the mapping.xml file.

2.5.3.20 MessgeBeanKeys This interface defines the constants for the properties used for message types and Message Beans.

Page 20: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 20

2.5.4 ActionHandler Classes and Interfaces

2.5.4.1 ActionHandler This interface defines the methods to be implemented by an ActionHandler.

2.5.4.2 ActionHandlerContext This class keeps track of all the ActionHandlers that are created and loaded for the framework and application.

2.5.4.3 AbstractActionHandler The AbstractActionHandler is an abstract class that implements the ActionHandler interface. It acts as the super class of all ActionHandler classes.

2.5.4.4 DefaultActionHandler The DefaultActionHandler class is a concrete subclass of the AbstractActionHandler class. It is used by the JadeGatewayServlet to process a request if NO ActionHandler is supplied as part of the URL parameters.

Page 21: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 21

2.5.5 Bean Classes and Interfaces

2.5.5.1 ExceptionBean The ExceptionBean can be used to store exception related information so that errors can be displayed in the JSP by accessing this from the result bean.

NOTE: At this time, the ExceptionBean class is not being used anywhere in the Jade Framework.

2.5.5.2 MessageBean The MessageBean is used to display messages to the user. The messages can be of several different types (errors, warnings, etc.) and can be formatted.

2.5.5.3 ModelCrawler The ModelCrawler interface defines the method collectResults() that must be implemented by all ViewBeans in order to retrieve data from the object model.

2.5.5.4 ResultBean The ResultBean is the container object that holds on to the StateBean, MessageBean and ViewBean. It is the interface for the JSP. All information the JSP needs is retrieved from the ResultBean.

Page 22: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 22

2.5.5.5 StateBean The StateBean represents a particular “state” of the application. This helps the servlet to figure out what to do next without making the servlet have to know this information.

2.5.5.6 ViewBean The ViewBean is the abstract super class of all application specific ViewBeans. It implements the ModelCrawler collectResults() method forcing subclasses to implement this method.

2.5.6 Exception Classes

2.5.6.1 JadeFrameworkException This class is the super class of all exceptions in the Jade Framework. This class differs from the class Exception by providing an extra constructor that takes Throwable as a parameter.

2.5.6.2 ActionHandlerContextInitializationException This exception is thrown when an error occurs while initializing the ActionHandlerContext.

2.5.6.3 ActionHandlerNotFoundException This exception is thrown when an error occurs while processing a request using the ActionHandler pattern and the ActionHandler is not found.

2.5.6.4 FrameworkInitializationException This exception is thrown when an error occurs while bootstrapping the Jade Framework.

2.5.6.5 LogContextInitializationException This exception is thrown when an error occurs while initializing the LogContext.

2.5.6.6 ParameterNotFoundException This exception is thrown while processing a request if the given parameter cannot be found.

2.5.6.7 ConfigContextInitializationException This exception is thrown when an error occurs while initializing the ConfigContext.

2.5.6.8 PropertyNotFoundException This exception is thrown when an error occurs while trying to load the configuration data from the property files.

2.5.6.9 ResultBeanException This exception is thrown when an error occurs while creating the ResultBean.

2.5.6.10 ViewBeanException This exception is thrown when an error occurs while creating the ViewBean.

Page 23: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 23

2.5.7 Session Classes and Interfaces

2.5.7.1 JadeSession This interface defines the methods that must be supported by a session object in the Jade Framework.

2.5.7.2 JadeSessionManagement This interface defines the methods that must be implemented by a class that provides an implementation for the JadeSession interface to manage the session object.

2.5.7.3 JadeSessionFactory This class is responsible for retrieving or creating a JadeSession object.

2.5.7.4 JadeHttpSession This class serves as a “wrapper” to the HttpSession object provided by the Servlet API. It implements the JadeSession and JadeSessionManagement interfaces thus enabling the HttpSession to be treated as a JadeSession.

Page 24: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 24

2.5.7.5 JadeIBMHttpSession This class serves as a “wrapper” to the IBMSession object provided by the WebSphere Application Server API. It implements the JadeSession and JadeSessionManagement interfaces thus enabling the IBMSession to be treated as a JadeSession.

2.5.8 Utility Classes and Interfaces

2.5.8.1 CacheControl The CacheControl class is to be used to force pages to expire. To force a page to expire, do the following:

CacheControl.setCache(request, response, expiration);

If you want a page to stay around use:

CacheControl.setNoCache(request, response);

2.5.8.2 DateFormatter This class provides utility methods for formatting the Date in the different formats.

2.5.8.3 ExceptionUtil This class is a utility class that facilitates dumping the exception stack trace in a String format for use in error reporting.

2.5.8.4 LogWriter This utility class is responsible for writing logs to a file.

2.5.8.5 CurrencyFormatter This class provides convenience methods for representing numbers as currency. In the future it will be enhanced to support different locales.

2.5.8.6 Parameters This class encapsulates the URL parameters that are passed from the browser using an HTTP GET or POST. The class is also used as a data structure for returning data from the process layer to the ResultBean.

2.6 Jade Resources In this section we discuss each and every resource file that is provided with the Jade Framework. The resource files associated with the applications will be discussed when we discuss the applications in detail.

Jade has a number of configuration files that must be understood in order to get the framework working:

The directory structure of Jade is as follows:

Page 25: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 25

• The following is a description of the directories:

jade - framework root dir

config - configuration root dir

action - action dir

i18n - internationalization properties dir (optional)

property - properties dir

log - default log dir

ead4j_jade_bootstrap.properties – This file contains basic information required by Jade to function. This file is absolutely necessary. Properties specified in this file are the code base for the framework on the operating system and names of the mandatory directories used by Jade to enforce the directory structure we discussed above. This file is only edited to change the code base. Constants representing these values are defined in the BootstrapKeys interface.

actionHandler.xml – This xml file is used to specify the ActionHandlers that come out of the box with Jade. Most applications will have their own actionHandler.xml file but can put their values in here if desired.

application.xml – This xml file is used to specify the applications that will be using Jade. One can specify multiple applications

device.xml – This xml file is used to specify the devices supported by this application e.g. Standard Browser. Most applications will have their own device.xml file but can put their values in here if desired.

html.xml – This xml file is used to specify html files that are used by Jade. Most applications will have their own html.xml file but can put their values in here if desired.

mapping.xml – This xml file is used to specify mapping of states specified by Jade. Most applications will have their own mapping.xml file but can put their values in here if desired.

message.xml – This XML file is where Jade stores its internal messages and defines message types and Message Bean types. Applications should have their own message.xml file for messages.

property.xml – This xml file is for ALL OTHER softly configurable properties used by Jade. Most applications will have their own property.xml file but can put their values in here if desired.

2.6.1 ead4j_jade_bootstrap.properties • Under the jade directory, there is a file called “ead4j_jade_bootstrap.properties”. In this file all the

components of Jade and their IMPLEMENTATIONS are specified. If for some reason, you want to write a customized implementation for a Jade component, you can do that and replace the default implementation.

• Here is a list of the editable entries in the file

jade.codeBase=C:\\Program Files\\IBM\\VisualAge for Java\\ide\\project_resources\\IBM EAD4J Jade\\

The code base property has to specify where the jade directory structure described above lies. Note this directory structure must lie in the classpath, for Jade to read the bootstrap file. The example above is the codebase during development.

Page 26: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 26

jade.traceState.key=ON

This property switches the trace messages on or off. Valid values are ON and OFF.

jade.applicationContext.class=com.ibm.ead4j.jade.config.ApplicationContextDefaultImpl

This property defines the implementation class of the ApplicationContext interface. One can specify a different implementation class if desired. The EAD4J framework comes with 2 other implementations for this interface – one for support with JNDI and one for pervasive support. See the ead4j_jade_bootstrap.properties directory for details.

jade.configContext.class=com.ibm.ead4j.jade.config.ConfigContextDefaultImpl

This property defines the implementation class of the ConfigContext interface. One can specify a different implementation class if desired. The EAD4J framework comes with another implementation for this interface for pervasive support. See the ead4j_jade_bootstrap.properties directory for details.

jade.i18nContext.class=com.ibm.ead4j.jade.config.I18NcontextDefaultImpl

This property defines the implementation class of the I8NContext interface. One can specify a different implementation class if desired. See the ead4j_bootstrap.properties directory for details.

jade.parameter.class=com.ibm.ead4j.jade.util.ParametersImpl

This property defines the implementation class of the I8NContext interface. One can specify a different implementation class if desired. . The EAD4J framework comes with another implementation for this interface for pervasive support. See the ead4j_bootstrap.properties directory for details.

jade.actionContext.class=com.ibm.ead4j.jade.action.ActionHandlerContextDefaultImpl

This property defines the implementation class of the I8NContext interface. One can specify a different implementation class if desired. See the ead4j_bootstrap.properties directory for details.

jade.log.path=C:\\Program Files\\IBM\\VisualAge for Java\\ide\\project_resources\\IBM EAD4J Jade\\jade\\log

This property allows one to set where Jade will do its logging. Jade by default has some basic logging to check to see that all is going well and by default it will log to the directory specified here. Note, a directory will not be created…the directory must already exist on the file system. The value specified above is for development.

jade.log.filename=JadeLog

This property specifies the name of the log that Jade creates for its internal logging purposes.

jade.log.writer=com.ibm.ead4j.jade.log.LogContextWriterAppend

This property specifies the implementation class for the LogContextWriter interface. There are three other implementations provided by EAD4J.

LogContextWriterAppend – Opens and closes the file each time a request is sent to the logger.

LogContextWriterSimple – logs to a file and always keeps the file open.

LogContextWriterJLog – Logs using the JLog logging API.

LogContextWriterLog4J – Logs using the Log4J logging API.

See the ead4j_bootstrap.properties directory for details.

jade.property.filename=property.xml jade.mapping.filename=mapping.xml jade.message.filename=message.xml

Page 27: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 27

jade.action.filename=actionHandler.xml jade.appl.filename=application.xml jade.html.filename=html.xml jade.devices.filename=device.xml

2.6.2 actionHandler.xml • This file is under jade\config\action.

• This file is used to list all the ActionHandlers defined and their fully qualified class names.

• This is necessary so that Jade can load all the action handlers at bootstrap time thus preventing performance at run time since all the action handler objects will be pre-instantiated.

• All one has to do is specify an ActionHandler name and the fully qualified class name

e.g.

<actionHandler>

<actionHandler-name>XYZ</actionHandler-name>

<actionHandler-class>com.xyz.XYZActionHandler</actionHandler-class>

</actionHandler>

2.6.3 i18n This directory is for reading properties that need internationalization support, such as currency. As of Jade 2.6, messages (including messages that require internationalization support) can be configured with the message.xml file. Therefore, i18n can be ignored in most situations.

2.6.4 application.xml • This file is under jade\config\property

• This file is used to specify as many applications as one wants so that Jade knows where THEIR CODEBASE is. This way one can create multiple applications that all use Jade.

<appl>

<appl-name>HBA</appl-name>

<appl-codebase>C:\Program Files\IBM\VisualAge for Java\ide\project_resources\HBA

</appl-codebase>

</appl>

2.6.5 device.xml • This file is under jade\config\property

• This file is used to specify the devices that the application will be supporting. This can be ignored for browser based web applications.

Page 28: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 28

2.6.6 html.xml • This file is under jade\config\property

• The file is used to tell Jade where to redirect to if an ERROR occurs, or if the SESSION times out.

e.g.

<jade-html>

<html>

<html-key>html.errorPage.name</html-key>

<html-name>itso_bank_error.jsp</html-name>

</html>

<html>

<html-key>html.homePage.name</html-key>

<html-name>index.jsp</html-name>

</html>

<html>

<html-key>html.invalidSessionPage.name</html-key>

<html-name>not_logged_in.html</html-name>

</html>

</jade-html>

2.6.7 mapping.xml • This file is under jade\config\property

• Jade uses this file for its internal mapping of some basic states. Ignore this.

• You could do your application-specific mapping in here, but its not advisable.

2.6.8 message.xml • This file is located under jade\config\property

• Jade uses this file for loading its internal messages and configuring message types and Message Bean types.

• This file does not need modified unless Jade is being specially configured.

• Application-specific messages should be defined in the application’s message.xml file.

2.6.9 property.xml • This file is under jade\config\property

• The file houses all the properties of Jade that can be tweaked.

• The properties of interest are:

<property>

Page 29: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 29

<key>jade.siteDebug.value</key>

<value>false</value>

</property>

By setting the value to “true” you get a nice error report with stack trace instead of an error page. Very useful during development.

<property>

<key>jade.logRequest.value</key>

<value>true</value>

</property>

By setting this value to false, the request will not be logged by Jade’s logging. You can turn this off during production.

<property>

<key>jade.session.type</key>

<value>com.ibm.ead4j.jade.session.JadeHttpSession</value>

</property>

By default Jade is configured to use the HttpSession object. In order for HttpSession to be configured we had to write an implementation class that implements the JadeSession interface and holds on the HttpSession object using composition. If one needs to, they can write their own implementation class for the JadeSession interface and specify it here.

<property>

<key>jade.session.auto.create</key>

<value>false</value>

</property>

By default Jade is configured to always not create a Session when using the JadeGatewayServlet. This is so that you can explicitly manage the session using a separate servlet. If you want to have the session automatically created, set the value to true. What this means is if the session times out a new one will be created on the next request.

<property>

<key>jade.store.bean.option</key>

<value>request</value>

</property>

By default, the JadeGatewayServlet will store all beans on the request always. If you want to store beans in session on every request ( for using frames for example ), set this to session.

<property>

<key>jade.hasUndo.key</key>

<value>true</value>

</property>

By default, the JadeGatewayServlet has an UNDO feature that stores the previous result bean in session so that the previous state can be recreated. To turn this feature off, set the value to false.

Page 30: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 30

<property>

<key>jade.method.forward</key>

<value>forward</value>

</property>

When doing the “mapping” of an application in the “mapping.xml” file, you can specify the “target-method” for the JadeGatewayServlet to use when processing a JSP. By default, the word “forward” is used to indicate a call to the RequestDispatcher forward() method of the Servlet API. To use a different word other than “forward” in the mapping.xml file, change the value of this property.

<property>

<key>jade.method.send.redirect</key>

<value>sendRedirect</value>

</property>

When doing the “mapping” of an application in the “mapping.xml” file, you can specify the “target-method” for the JadeGatewayServlet to use when processing a JSP. By default, the word “sendRedirect” is used to indicate a call to the HttpServletRequest sendRedirect() method of the Servlet API. To use a different word other than “sendRedirect” in the mapping.xml file, change the value of this property.

NOTE: When using sendRedirect in your mapping as the target method, the result bean will automatically be stored in session. This is because in order for a JSP to get access to the data, the result bean has to be in session.

<property>

<key>jade.method.transcode</key>

<value>transcode</value>

</property>

When doing the “mapping” of an application in the “mapping.xml” file, you can specify the “target-method” for the JadePervasiveGatewayServlet to use when processing the view for a pervasive device. By default, the word “transcode” is used to indicate a call to the transcoder. To use a different word other than “transcode” in the mapping.xml file, change the value of this property.

<property>

<key>jade.action.key</key>

<value>jadeAction</value>

</property>

By default, when using the ActionHandler support of Jade, the action key specified as part of the URL is “jadeAction” e.g. http://localhost:8080/HBA/hbaGateway?jadeAction=HBA_LOGIN_HANDLER. To change the value to something more “customized”, one can change the value of this property to whatever one likes and then use that as the action key in the URL.

Page 31: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 31

2.7 Application Configuration with Jade Jade allows an application to specify its directories separate from the Jade directories. However if specified separately, a lot of the directory structure still stays the same. You still need the following:

config - configuration root dir

action - action dir

i18n - internationalization properties dir (optional)

property - properties dir

In the above picture “HBA” is the end of the application code base and then we have the same directory structure as Jade does underneath the code base.

A lot of the files are also similar. See below:

2.7.1 actionHandler.xml • This file is under <APPLICATION CODEBASE>\config\action.

• This file is used to list all the ActionHandlers defined and their fully qualified class names.

• This is necessary so that Jade can load all the actionhandlers at bootstrap time thus preventing performance at run time since all the action handler objects will be pre-instantiated.

• All one has to do is specify an ActionHandler name and the fully qualified class name

e.g.

<actionHandler>

<actionHandler-name>XYZ</actionHandler-name>

<actionHandler-class>com.xyz.XYZActionHandler</actionHandler-class>

</actionHandler>

2.7.2 ActionHandler file modifications The Action Handler XML file to deal with ProcessContract has an extra element as depicted below: <?xml version="1.0" encoding="UTF-8"?>

Page 32: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 32

<!-- Begin Embedded DTD -->

<!DOCTYPE actionHandler-config [

<!ELEMENT actionHandler (actionHandler-name,actionHandler-class,actionHandler-description?,actionHandler-formBean?)>

<!ELEMENT actionHandler-class (#PCDATA)>

<!ELEMENT actionHandler-config (actionHandler+)>

<!ELEMENT actionHandler-name (#PCDATA)>

<!ELEMENT actionHandler-description (#PCDATA)>

<!ELEMENT actionHandler-formBean (#PCDATA)>

]>

<!-- End Embedded DTD -->

<actionHandler-config>

<actionHandler>

<actionHandler-name>HBA_LOGIN_HANDLER</actionHandler-name>

<actionHandler-class>itso.bank.action.LoginActionHandler</actionHandler-class>

<actionHandler-formBean>itso.bank.formBean.LoginForm</actionHandler-formBean>

</actionHandler>

<actionHandler>

<actionHandler-name>HBA_LOGOUT_HANDLER</actionHandler-name>

<actionHandler-class>itso.bank.action.LogoutActionHandler</actionHandler-class>

</actionHandler>

Notice that Jade allows a mix of the (old) Standard way with the new API with Process Contracts to coexist in a application, this gives the developer a lot of flexibility.

Also note that the Process Contract element is optional.

2.7.3 i18n With Jade versions prior to version 2.5, this directory was used for reading properties files that contained messages that possibly required internationalization support. While this functionality is still supported, it is recommended that all application messages be defined in the application-specific message.xml file.

If using the older i18n method is desired, message files must be stored in the i18n directory as .properties files. They can then be retrieved using either the getMessage(String,Locale,String) or getMessage(String,String) methods in ApplicationContext by passing in the ResourceBundle name. This directory is optional and the files can actually be placed ANYWHERE IN THE CLASSPATH.

2.7.4 device.xml • This file is under <APPLICATION CODEBASE>\config\property

2.7.5 html.xml • This file is under <APPLICATION CODEBASE>\config\property

• This file can be used to define all the HTML files used by the site so that any references to the pages can be done using constants on the JSP.

Page 33: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 33

• In addition the error page and session time out page can be placed here if one does not want to couple the application properties with Jade

2.7.6 mapping.xml • This file is under <APPLICATION CODEBASE>\config\property

• This file is very important. Here one lists all the states and all the ViewBeans used by the application. After that one defines a mapping one by one for a state to a ViewBean and JSP. One can also decide whether to use a FORWARD or a SENDREDIRECT for the JSP processing.

Here’s some excerpts from the HBA application:

<!- - some states - - >

<state-config>

<state>

<state-name>HBA_LOGIN_SUCCESSFUL</state-name>

</state>

<state>

<state-name>HBA_LOGIN_UNSUCCESSFUL</state-name>

</state>

<state>

<state-name>HBA_DISPLAY_ACCOUNTS</state-name>

</state>

</state-config>

<!- - some views - - >

<view-config>

<view>

<view-name>CustomerView</view-name>

<view-class>itso.bank.viewobjects.CustomerView</view-class>

</view>

<view>

<view-name>BankAccountView</view-name>

<view-class>itso.bank.viewobjects.BankAccountView</view-class>

</view>

<view>

<view-name>EmptyViewBean</view-name>

<view-class>itso.bank.viewobjects.EmptyViewBean</view-class>

</view>

<view>

Page 34: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 34

<view-name>LogoutViewBean</view-name>

<view-class>itso.bank.viewobjects.LogoutViewBean</view-class>

</view>

<view>

<view-name>BankAccountViewList</view-name>

<view-class>itso.bank.viewobjects.BankAccountViewList</view-class>

</view>

<!- - some mapping - - >

<mapping-config>

<mapping>

<state-name>HBA_LOGIN_SUCCESSFUL</state-name>

<locale key="">

<view-name>CustomerView</view-name>

<target content-type="text/html">accounts.jsp</target>

<target-method>FORWARD</target-method>

</locale>

</mapping>

<mapping>

<state-name>HBA_DISPLAY_ACCOUNT_BALANCE</state-name>

<locale key="en_US">

<view-name>BankAccountView</view-name>

<target content-type="text/html">account_balance.jsp</target>

<target-method>FORWARD</target-method>

</locale>

</mapping>

<mapping>

<state-name>HBA_LOGIN_UNSUCCESSFUL</state-name>

<locale key="en_US">

<view-name>EmptyViewBean</view-name>

<target content-type="text/html">unsuccessful_login.jsp</target>

<target-method>FORWARD</target-method>

</locale>

</mapping>

<mapping>

<state-name>HBA_LOGOUT_SUCCESSFUL</state-name>

Page 35: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 35

<locale key="en_US">

<view-name>LogoutViewBean</view-name>

<target content-type="text/html">logout.jsp</target>

<target-method>FORWARD</target-method>

</locale>

</mapping>

</mapping-config>

2.7.7 message.xml • This file is located under <APPLICATION CODEBASE>\config\property

• This file is used for loading application messages.

• Messages can be of any of the message types defined in the Jade message.xml file.

• Messages can have text for multiple languages.

Here is an example:

<message-config>

<message>

<!-- 3 languages –->

<key>HELLO_MSG_KEY</key>

<type>JADE_MESSAGE_TYPE_INFO</type>

<text locale="en_US">Hello</text>

<text locale="es_ES">Hola</text>

<text locale="fr_FR">Bonjour</text>

</message>

<message>

<!—- 2 languages -->

<key>LANGUAGE_ERROR_MSG_KEY</key>

<type>JADE_MESSAGE_TYPE_ERROR</type>

<text locale="en_US">I don’t speak English</text>

<text locale="es_ES">No hablo Espanol</text>

</message>

<message>

<!—- 1 language (likely the JVM default lanugage) -->

<key>APPLICATION_ERROR_MSG_KEY</key>

<type>JADE_MESSAGE_TYPE_ERROR</type>

<text locale="en_US">An application error has occurred</text>

Page 36: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 36

</message>

</message-config>

2.7.8 property.xml • This file is under <APPLICATION CODEBASE>\config\property

• The file can be used to house all kinds of name-value properties needed by the application.

See the HBA application for examples of putting what you like here.

Page 37: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

2.8 Jade Programming Models

2.8.1 Single Servlets or Multiple Servlets The Single Servlet approach allows a single servlet to be used to dispatch requests to different ActionHandlers, it is very useful when the servlet code is very repetitious, but some considerations should e addressed:

1. Single Servlets should be used in an in-regime mode that is after a valid session was obtained, most certainly through another servlet.

2. Some of the tools that do web usage profiling might not return meaningful results with the single servlet approach.

3. It’s easier to divide work with the Single Servlet approach.

4. The Single Servlet approach the code is not as easy to read as in the Multi Servlet.

5. The Single Servlet approach does not mean the application will have only one servlet, the Single Servlet example provided with the framework has three Servlets.

2.8.2 Flow of Control – Single Servlet Model From a developers point of view the flow of control is as follows:

A given page is already rendered to a user, this page can be a HTML page or a JSP. This page contains either a link or a button.

When the user either clicks on the link or in the button the Gateway Servlet is invoked through an HttpRequest. In this request that is sent to the Servlet and action code is also sent in. This action maps to a specific ActionHandler.

So for each different action an ActionHandler must be mapped. In the background when this servlet is invoked, it looks up an ActionHandler class, and invokes a method on it.

e Internet

Gateway

Click Her

IBM Confidential

OK

Request jadeAction=LOGIN

Servlet

itso.baAc

ActionHandler Lookup

37

LOGIN nk.action.LogintionHandler

Page 38: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 38

Therefore the main steps to use the Single Servlet approach are as follows:

• In the HTML every different user action must be defined by a key.

a. In the sample HBA application the key HBA_DISPLAY_ACCOUNTS_ACTIONHANDLER is the value defined to display accounts.

• Since it is not good policy to “hard-code” either HTML/JSP or Java code, this action should be defined in an interface. This allows changes to the specific value to be changed in a centralized place.

a. In the example HBA application this is defined in the HBAActionHandlerKeys interface.

• The HTML /JSP should be coded to handle this action either through a Get or Post.

a. Example

If the method is a Post

<FORM METHOD=POST ACTION=”/servlet/com.ibm.ead4j.jade.servlet.JadeGatewayServlet”>

<INPUT TYPE=TEXT>Text Field</INPUT>

<INPUT TYPE=SUBMIT NAME=”BUTTON” VALUE=”BUTTON”></INPUT>

<INPUT TYPE=HIDDEN NAME=”jadeAction” VALUE=” HBA_DISPLAY_ACCOUNTS_ACTIONHANDLER”>

</FORM>

If the method is a get

<A href="=”/servlet/com.ibm.ead4j.jade.servlet.JadeGatewayServlet?jadeAction= HBA_DISPLAY_ACCOUNTS_ACTIONHANDLER">Click Here</A>

At this point the action is defined, but it is now necessary to define an ActionHandler (the Class) to handle this action.

• Create the ActionHandler Class, by sub-classing it from AbstractActionHandler.

Page 39: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 39

a. In the HBA example this class is the DisplayAccountsActionHandler, make sure that this class extends the AbstractActionHandler class and implements the execute method.

• Add an entry to the actionHandler.xml file that has the key as defined in the interface and the fully qualified class name.

actionHandler.xml file

<actionHandler-config>

<actionHandler>

<actionHandler-name>HBA_DISPLAY_ACCOUNTS_HANDLER</actionHandler-name>

<actionHandler-class>itso.bank.action.DisplayAccountsActionHandler

</actionHandler-class>

</actionHandler>

</actionHandler-config>

b. In the HBA example this entry is in the actionHandler.xml file and the entry is:

<actionHandler-class>itso.bank.action.DisplayAccountsActionHandler

</actionHandler-class>

At this point the action is defined and the ActionHandler class to handle the action and the key to find it are defined.

The next step is to define the state the application will be in after executing this action.

• Define a key for each state in an interface.

a. In the example HBA application the key HBA_DISPLAY_ACCOUNTS will define this state.

• For each state define also in an interface the JSP that can handle the application in this state and the View Bean that can display the dynamic data.

a. In the HBA example the HBA_DISPLAY_ACCOUNTS is defined in the HBA_VIEW_KEYS interface.

• View Bean keys should be the State key prefixed with sfwView.

• Define a View Bean class that will implement the collectResults method and that will be able to display the information that will be presented by the JSP.

Page 40: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 40

b. In the HBA example this class is the BankAccountViewList.

c. Make sure that this class extends the Abstract ViewBean class and that the collectResults is defined.

2. Create an entry on the properties file for the ActionHandlers to reference this class.

3. Define a state that the application will be in after successfully running this action.

4. Define this key in an interface.

5. Define an entry in the mapping.xml file for the views that maps the state to the view.

a. First list the state in the HBA example this entry maps the HBA_DISPLAY_ACCOUNTS state to the BankAccountViewList view bean class.

b. Then list the view

c. Finally define the mapping between the state and the view

<state-config>

<state>

<state-name>HBA_DISPLAY_ACCOUNTS</state-name>

</state>

</state-config>

<view-config>

<view>

<view-name>BankAccountViewList</view-name>

<view-class>itso.bank.viewobjects.BankAccountViewList</view-class>

</view>

</view-config>

<mapping-config>

<mapping>

<state-name>HBA_DISPLAY_ACCOUNTS</state-name>

<locale key="en_US">

<view-name>BankAccountViewList</view-name>

<target content-type="text/html">account_information.jsp</target>

<target-method>FORWARD</target-method>

</locale>

Page 41: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 41

</mapping>

</mapping-config>

2.8.3 Flow of Control – Multiple Servlets Model From a developers point of view the flow of control is as follows:

A given page is already rendered to a user; this page can be a HTML page or a JSP. This page contains either a link or a button.

When the user either clicks on the link or in the button the specific Servlet is invoked through an HttpRequest. Since the servlet is specific it knows what action to perform and what process object to invoke. You can use action handlers if the servlet plans to handle more than one task. See the flow above for understanding how servlets work with action handlers

.

3. Designing EAD4J Jade Applications

3.1 Creating JSPs JSPs can be created as usual using an HTML editor or WYSIWYG tool. The thing to remember is that all JSPs should inherit from the BaseJSP class or delegate to the JSPHelper class of the Jade Framework. Inheritance should be accomplished as follows:

<%@ page extends = "com.ibm.ead4j.jade.jsp.BaseJSP" errorPage = "<whatever your error page is>" %>

While delegation should be accomplished as follows:

<%@ com.ibm.ead4j.jade.jsp.JSPHelper help = com.ibm.ead4j.jade.jsp.JSPHelper.singleton(); %>

Remember, also that the syntax shown above is JSP 1.0 compliant.

NOTE: A ClassCastException can occur if the ViewBean defined in the XML configuration file is different from the one expected by the JSP.

3.2 Creating Servlets There are a couple of things to keep in mind before starting to develop your servlets.

1. If you choose to use the Single Servlet Programming Model, one can choose whether to allow the gateway servlet to handle session management or not. If no, then the only servlets you will have to develop are the login and logout servlet. Otherwise, the gateway servlet will always assume that it can retrieve a valid session and if there isn’t one, it will create one.

2. Again, please note that if you decide to use the Single Servlet Programming Model, it means you are committing yourself to using the Jade ActionHandler Pattern that comes along with it and helps to process requests. The additional servlets that you create do not have to use ActionHandlers if they like.

3. If you choose to use the Multiple Servlet Programming Model, again there are several choices. There is a choice of whether you will use ActionHandlers or not. This is an architectural decision that must be made. ActionHandlers are quite useful because they avoid the possibility of the servlet’s doGet/doPost/service() method from getting too big and complicated. They also make the solution more scalable because ever so often a servlet that was initially handling a certain kind

Page 42: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 42

of request is now required to handle another kind of request related to the same area of functionality. If you want to have some servlets use ActionHandlers and some not, that can be done too. All application servlets developed using this model will inherit from the JadeBaseMultiServlet.

4. Instance variables – Where one can, one should avoid the use of instance variables in a servlet. It is very rare that one would require storing state in a servlet using Jade. It is better to use the servlet as a pass through mechanism to pass the parameters on to the appropriate classes further down in the layers. This can help avoid threading issues, as the web server will spawn different threads for executing servlet requests, as it needs to.

5. When developing your own application-specific servlets in the Multiple Servlet Programming Model, make sure you use this snippet of code in your doGet or doPost:

if ( resultBean.

getStateBean()

.getStateAsString()

.equals(context.getConfigParameter(Jade_UNDO_STATE_KEY)))

{

this.handleUndo(request, response, resultBean.getMessageBean());

}

else

{

//process the result...set the cache control to no cache

this.processResult(request, response, resultBean,0);

//or use:

//this.processResult(request, response, resultBean,3000);

}

This is extremely useful. What this does is ensures that if for some reason, something goes wrong and you decide to put things back in the state they were before this particular task had been executed, that the previous state of the application is maintained. Example: Let’s say you try to transfer some funds and between the same account numbers and the back end throws an exception. You can keep the user on the same page and just display a message without having to code the logic to repaint the page. Review the code in the VSTORE application to understand this better.

NOTE: Generally always create a servlet class that inherits from one of the Jade servlets to be the parent of your application servlets. This way, if ever you want to break off from Jade, your code will not be tightly coupled. Also over time you will generally find that there is common functionality that you can move into this super class.

3.3 Creating/Using Parameters A Parameters object encapsulates the input data that comes from the HTTP request either using a GET or a POST. The object can be created as follows:

//servlet layer

Page 43: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 43

Parameters params = this.createParameters(request,response);

To create a parameters object in a layer other than the servlet layer, use the ParametersFactory.

e.g.

Parameters params = ParametersFactory.create()

This will create an empty Parameters object and then data can be added to it as needed.

Once the Parameters object is created you can retrieve values from it by giving it the name of the parameter you are looking for. The best part is that if you want the parameter value in a certain Java type, so that the value can be passed or set on a Process/Domain Object, you can do so by using the convenience methods provided. Here are some examples:

int i = params.getParameterAsInt(“param_name”);

float f = params.getParameterAsFloat(“param_name”);

BigDecimal amt = params.getParameterAsBigDecimal(“param_name”)

String str = params.getParameterAsString(“param_name”);

boolean flag = params.getParameterAsBoolean(“param_name”);

3.4 Creating/Using JadeSession The usual HttpSession or IBMSession are encapsulated around an interface in the framework. This is done so that different session implementations can be added either by specific application needs or by future enhancements to the framework.

Therefore to create a new session, one must first decide either to use the HttpSession or the IBM specific IBMSession.

In the sample application we have chosen to use the HttpSession.

The first thing to do is to edit the property.xml file under the jade\config\property directory by checking the following line:

<property> <key>jade.session.type</key> <value>com.ibm.ead4j.jade.session.JadeHttpSession</value>

</property>

This will tell the framework that the type of session the application wants instantiated, please note that this allows any homegrown session management system to be plugged in. As long of course that it implements the JadeSession and JadeSessionManagement interfaces.

The only task that a servlet has to do is to create or retrieve a session is call the super class methods:

JadeSession jadeSession = this.createSession(request);

OR

JadeSession jadeSession = this.getSession(request);

Page 44: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 44

To create a session directly without using the JadeBaseHttpServlet API….use

JadeSession jadeSession = JadeSessionFactory.create(request);

As you can see, you still need access to the HttpServletRequest object

3.5 Creating ActionHandlers With some careful design ActionHandlers allow the application written to handle requests from servlets to also serve requests from other devices. The developer should consider using the ActionHandlers to shield the application from changes that can occur in the UI layer.

Every ActionHandler must extend the AbstractActionHandler class, this assures that the execute method will be implemented. The execute method usually follows a pattern:

An object is retrieved from the JadeSession (2). This object must not be a live object, but a lightweight representation of a live object.

The lightweight object is added to the input Parameters (3).

The Process Object instance is located, either through some look up mechanism or naming service or is instantiated.

A business method is invoked in the Process Object (4).

The ActionHandler returns the Result Bean (5).

The variations are related to retrieving or not an object from the session, or if a Process Object is involved in the method invocation. Please check the following discussion on Shallow and Deep ActionHandlers for a more descriptive analysis on this matter.

NOTE: Generally always create an action handler class that inherits from the Jade AbstractActionHandler to be the parent of your application action handlers. This way, if ever you want to break off from Jade,

Page 45: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 45

your code will not be tightly coupled. Also over time you will generally find that there is common functionality that you can move into this super class.

3.5.1 Shallow & Deep ActionHandlers In most cases ActionHandlers interact with process objects, as described in the Jade Framework architecture and reference document. These ActionHandlers we have named Deep ActionHandlers, because their interactions affect the business object model layer and are usually modeled by Use Cases.

There are however interactions that do not affect the business object layer and that might not be fully represented by Use Cases, these are UI interaction such as menu options and navigational selections. In this cases it might not be necessary to have the ActionHandlers interact with the business object layer.

Therefore these ActionHandlers don’t have to communicate with the Process Object and can handle themselves the navigational issues. For these reason these ActionHandlers we have named Shallow ActionHandlers.

To further understand what is going on lets understand what the framework defines as application state.

3.5.1.1 Jade Application State Application state in the class book definition could lead the developer to model a complete state transition diagram for the application. This application state is not UI related but its related to the actual state the application is in after a business method execution.

What Jade defines as state is a scale down version of Application state, it is more UI related than the actual application state. What Jade tries to accomplish is to de-couple the UI to be displayed from the business method invocation in the Process Object.

This is accomplished through the Jade Application State. These states define from a UI perspective what are the state(s) the application is in. An example might be that after a withdrawal operation in an account from the Application point of you the state is WITHDRAWAL_OK, but from the UI perspective the state is DISPLAY_BALANCE.

3.5.1.2 How Shallow and Deep ActionHandlers fit into the picture One of the paradigms of the Framework is to follow the Model – View – Controller concept. The ActionHandlers the framework defines sit right in between the UI/Controller and the Model. They translate calls from the UI into correct calls into the model, they can be completely dumb as to just sit in between and serve as a pass through mechanism, or they can do some work of their own.

These two areas, the Framework Application State, and the degree of participation in the UI logic are where the concept of Shallow and Deep ActionHandlers come to play.

In some cases the UI directs the Model to a business transformation, for example an withdrawal operation, in this case after a successful operation a account should be updated with a new balance, a transaction record recorded and so on. In this case the ActionHandler should not get involved, except maybe to retrieve / store values to the session. This in an example of a Deep ActionHandler, because the ActionHandler in it’s execution goes all the way to the model.

In other cases the UI does not direct the Model to a business transformation, for example to display a menu of options. In this case the ActionHandler does not have to go all the way to the Model, it could create the correct Result Bean with maybe some value store in session, and send it back. This is an example of shallow ActionHandlers because the ActionHandler does not go all the way to the Model.

Side Bar:

Page 46: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 46

When coding ActionHandlers there might be situations when the first time around an ActionHandler might function as a Deep ActionHandler and the subsequent ones as a Shallow ActionHandler. This is the case with values that have to be read from the Model, but after the first read their values for the scope of an interaction will not change. Maybe this is a list of stores for a company, in the first interaction the developer could go to the model and retrieve all the stores, in the next requests these values could be retrieved from the Session.

3.6 Creating State Beans For each different UI to be displayed a State has to be created, this state must be defined in a interface, and a corresponding entry has to be added to the application-specific “mapping.xml” file which maps the state to the proper page so that any change is localized. The following is an example of the interface used by the sample application:

public interface HBAStateKeys extends StateKeys

{

public static final String HBA_LOGIN_SUCCESSFUL = "HBA_LOGIN_SUCCESSFUL";

public static final String HBA_LOGOUT_SUCCESSFUL = "HBA_LOGOUT_SUCCESSFUL";

public static final String HBA_DISPLAY_ACCOUNTS = "HBA_DISPLAY_ACCOUNTS";

}

The StateBean class only encapsulates a String, this string defines the Framework Application State.

Here are the entries for the mapping.xml file

<state-config>

<state>

<state-name>HBA_LOGIN_SUCCESSFUL</state-name>

</state>

<state>

<state-name>HBA_LOGIN_UNSUCCESSFUL</state-name>

</state>

<state>

<state-name>HBA_LOGOUT_SUCCESSFUL</state-name>

</state>

</state-config>

<mapping-config>

<mapping>

Page 47: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 47

<state-name>HBA_LOGIN_SUCCESSFUL</state-name>

<locale key="en_US">

<view-name>CustomerView</view-name>

<target content-type="text/html">accounts.jsp</target>

<target-method>FORWARD</target-method>

</locale>

</mapping>

3.6.1 Defining a state for every user interaction Each UI interaction with the system can potentially change the Framework Application State, this change however does not indicate that a change in the application state, please refer to item 2.3.1.1.

In Deep ActionHandlers the StateBean is created by the Process Object and passed in to the collectResults method through the Parameters object.

In Shallow ActionHandlers the ActionHandler Object creates the StateBean. The following is a sample code for the StateBean creation:

StateBean stateBean = StateBeanFactory.create( HBA_DISPLAY_ACCOUNT_BALANCE );

The stateBean is usually added to a Parameters object with the convenience method: setCurrentStateBean that sets the Bean using an appropriate key.

StateBean StateBean = StateBeanFactory.create(HBA_DISPLAY_ACCOUNT_BALANCE);

handler.setState(stateBean);

or

handler.setState(HBA_DISPLAY_ACCOUNT_BALANCE);

3.7 Creating View Beans View Beans is an abstract class for all View Beans that the application will handle with the ResultBean. What this means is that for any given page there is only one ViewBean class that handles all the UI requirements for the page. Therefore if a page has to display multiple beans the ViewBean class for the page will be a container for these beans. The Container class has to extend the ViewBean class, but the contained do not, for example:

A Page might have as needed beans, a Customer Bean and a List of Accounts, the View Bean for this page might be UserAccountViewBean, it would extend the ViewBean class and implement the collectResults method. It also would have two associations, one with a CustomerBean and a collection of Account Beans. These two classes wouldn’t need to extend the ViewBean class or implement the collectResults method.

In this case the only bean that would have to extend and implement the collectResults method would be the BankListBean.

Page 48: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 48

The class definition of these classes could be as follows:

public class BankListBean extends ViewBean

implements java.io.Serializable, HBAViewKeys

{

private AccountBean[] fieldAccounts = null;

private CustomerBean customer = null;

}

public final class CustomerBean

implements java.io.Serializable, HBAViewKeys, HBAStateKeys

{

private String fieldFirstName = new String();

private String fieldLastName = new String();

private String fieldTitle = new String();

private String fieldUserId = new String();

N1

View Bean

Customer Bean Account Bean

Bank List Bean

Customer

accounts

Page 49: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 49

private String fieldCustomerId = new String();

}

public class AccountBean

implements java.io.Serializable, HBAViewKeys, HBAStateKeys

{

private String balance;

private String accountId;

private String accountType;

}

Every page to be displayed needs one ViewBean, but this bean can like shown in the example be just a wrapper to the actual beans. In some cases this can make the beans themselves more re-usable.

NOTE: The original concept of “view objects” was first discussed in the Redbook “SG24-5423-00 Developing an e-business Application for the IBM WebSphere Application Server”. The concept stated that one create lightweight beans that were the flat versions of the object model. This concept works for small applications, but does not scale to large JSP applications. However, by using the concept provided in the Redbook in conjunction with the ViewBean concept provided by Jade, one can achieve a scalable solution by creating reusable “view objects” based on the object model and then defining a ViewBean for every JSP as a container for these “view objects”. In this way, one has a unique ViewBean for every JSP that reuses lightweight view objects. See the HBA and HBAM code for more details.

3.7.1 Implementing the ModelCrawler interface The collectResults method from the ModelCrawler interface allows the developer to get a handle to a live object and to flatten these live objects into beans that can be used by the JSPs.

Inside the CollectResults method a Transaction should already be established, so the Object(s) retrieved from the Parameters Object are live objects.

The implementation usually also follows also a pattern:

First the live object(s) is retrieved from the Parameters object (1).

Next some attributes from the live object(s) are read (3) and stored into the View Bean (4).

Page 50: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 50

3.8 Creating Message Beans Message Beans are used to send messages to the JSP to display to the user. Often the user has to be informed of events that occur in the application for example – registration confirmed or order processed. Also often the user has to be notified about an error that has occurred such as invalid password entered or transaction could not be processed. Jade provides support for messaging and gives the developer several ways to go about doing this.

3.8.1 Messages in the Process Object Layer Often when a task is being handled in the process layer, the developer may want to set a message that would be propagated to the user when the next screen is displayed. The ResultHandler should be used to add messages to the MessageBean in this situation. Here is an example:

// in a method of a process object

handler.setState(ORDER_SUCCESSFUL);

customer = BankHome.getBank().getCustomerByUserId(userId);

handler.addParameter(HBA_CUSTOMER_KEY, customer);

handler.addMessage(appCtx.getMessage(ORDER_SUCCESSFUL_MSG_KEY));

or

handler.addMessage(“Your order was successful.”);

Page 51: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 51

3.8.2 Messages in the View Bean Layer Messages that are needed for the user are often UI specific and therefore should not be created in the Process Object layer. In order for UI specific messages to be added, the best place to create these messages is the collectResults() method of the View Bean. The ResultBean assists in this operation by creating an empty MessageBean ahead of time. The MessageBean must be retrieved from the ResultBean, then messages can be added.

Here is an example:

// in the collectResults method of a ViewBean

if (stateBean.getState().equals(HBA_ADD_PAYEE))

{

BankCollection payeeAccounts

= (BankCollection) parameters.getParameter(

HBA_PAYEE_ACCOUNTS_KEY);

PayeeAccountViewList payeeAccountsView

= new PayeeAccountViewList(payeeAccounts );

this.setPayeeAccounts( payeeAccountsView );

MessageBean mBean =

(MessageBean) parameters.getParameter(JADE_MESSAGE_RESULT_KEY);

mBean.addMessage("New Payee added successfully!");

or

MessageBean mBean = MessageBeanFactory.create(“New Payee added successfully!”);

3.8.3 Messages in the ActionHandler Layer Developers may choose to create the MessageBean in the ActionHandler layer because the ResultBean (or Object) returned from the Process Layer is null and the user has to be informed that something went wrong with the requested function. The following is an example where the ResultBean is created with the ResultHandler using the UNDO state and a message with information retrieved from the exception is added.

ApplicationContext context = ApplicationContextFactory.singleton().getApplicationContext();

try

{

AccountsProcess.singleton().prepareTransferFunds( parameters );

return resultBean;

}

catch ( Exception e )

Page 52: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 52

{

LogContext.singleton().logError( e.toString() );

ResultHandler handler = new ResultHandler(params);

handler.setState(BIS_SFW_UNDO_STATE_KEY);

handler.addMessage(e.toString()); return handler.getResultBean();

}

3.8.4 Messages in the Servlet Layer As mentioned in an earlier section, if you decide your servlets and make them talk directly to the Process Object, then the job of handling an error and potentially setting a message may occur here. The code would look identical to the one above.

3.8.5 Multiple Messages The MessageBean interface supports the capability to store multiple messages. Messages can be added in order, or messages can be added in an unordered fashion using specific keys.

The easiest way to add ordered messages is as follows:

ResultHandler handler = new ResultHandler(params);

handler.addMessage( “ABC”);

handler.addMessage(“XYZ”);

handler.addMessage(“123”);

or

MessageBean mBean = MessageBeanFactory.create();

MBean.addMessage(“ABC”);

MBean.setMessage(0,”XYZ”); // replace the first ordered message

The easiest way to add unordered (keyed) messages is as follows:

ResultHandler handler = new ResultHandler(params);

handler.addKeyedMessage(MSG_1_KEY, “ABC”);

handler.addKeyedMessage(MSG_2_KEY,”XYZ”);

3.8.6 Pre-defined Messages Messages that are pre-defined in the message.xml file are the easiest to use and offer the most functionality. When using message.xml files, Jade stores all messages as Message objects. These objects contain a message key, message text (in multiple languages if necessary), and a message type. To use these

Page 53: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 53

predefined messages, the ResultHandler can be used or the MessageBean can be accessed directly. The following are two examples:

ResultHandler handler = new ResultHandler(params);

handler.addMessage( appCtx.getMessage(LOGIN_SUCCESS_MSG_KEY));

or

MessageBean mBean = MessageBeanFactory.create();

mBean.addMessage(appCtx.getMessage(LOGIN_SUCCESS_MSG_KEY));

3.8.7 Pre-defined Messages With Multiple Languages Messages that are defined in the message.xml file can contain more than one language. The default language used is the defined by the JVM’s default Locale. This can be overridden by specifying the desired Locale. The following is an example:

ResultHandler handler = new ResultHandler(params);

handler.addMessage( appCtx.getMessage(LOGIN_SUCCESS_MSG_KEY,

new Locale(“en”,”US”)));

or

MessageBean mBean = MessageBeanFactory.create();

mBean.addMessage(appCtx.getMessage(LOGIN_SUCCESS_MSG_KEY,

new Locale(“es”,”ES”)));

3.8.8 Message Types Message types were introduced with Jade version 2.5 in order to differentiate between different categories of messages. Messages can have one of several default types. Oftentimes, the user interface is designed to display messages in different ways or in different locations depending on their type. Jade defines four message types: ERROR, WARNING, INFO, and SUCCESS. These constants are defined in the MessageBeanKeys interface. The Jade message.xml file configures these types and also specifies the default message type. Any messages that are added to the MessageBean without specifying a specific type will use the default message type. The following is an example of specifying a message type:

ResultHandler handler = new ResultHandler(params);

handler.addMessage(“System error”,ERROR);

handler.addMessage(“Invalid database configuration”,WARNING);

3.8.9 Message Display Formatting

Page 54: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 54

Messages can be one of several types and can be formatted based on this type as well. The JSP developer has full control over how each message type is displayed. The default MessageBean is a class that supports the special formatting of messages. The following is an example of formatting messages in a JSP:

<% MessageBean messageBean = resultBean_currentResult_key.getMessageBean(); %>

<%-- Display warning messages with using the ‘warning’ style --%>

<%= messageBean.formatMessages(messageBean.WARNING,"<UL>",

"<LI class='warning'>","</LI>","</UL>") %>

<%-- Display success messages with using the ‘success’ style --%>

<%= messageBean.formatMessages(messageBean.SUCCESS,"<UL>",

"<LI class='success'>","</LI>","</UL>") %>

<%-- Display error messages with using the ‘error’ style --%>

<%= messageBean.formatMessages(messageBean.ERROR,"<UL>",

"<LI class='error'>","</LI>","</UL>") %>

If the MessageBean does not contain messages of a certain type (or contains no messages as all), nothing will be displayed for that type. If the MessageBean in the above example contained two messages of type ERROR, the following is an example of the output of the formatMessages method:

<UL><LI class=’error’>Some message text</LI>

<LI class=’error’>More message text</LI></UL>

Formatting of messages in this manner gives the JSP/HTML developer the ability to use specific style sheet elements or HTML tags to put messages in a list or a table for example.

3.8.10 Message/Location Key Linking In some user interfaces it is desirable to place certain messages in specific areas. For example, on a login screen, a “User ID is invalid” message may best be placed near the user ID input field (this, of course, depends on the interface design requirements). Each message contained within the MessageBean can be associated or linked to a specific location key. Then the specific message for a particular location key can be retrieved from within the JSP for display in a special screen location. Messages are not required to be linked to a location key. Unlinked messages are displayed together as described in previous sections, often at the top of a screen.

<% MessageBean messageBean =

resultBean_currentResult_key.getMessageBean(); %>

<INPUT type=”text” name=”USER_ID_KEY”>

Page 55: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 55

<%= messageBean.formatMessageForLocation(messageBean.ERROR,

viewBean.USERID_KEY,”<LI class=’error’>”,”</LI>” %>

<BR>

<INPUT type=”text” name=”PASSWORD_KEY”>

<%= messageBean.formatMessageForLocation(messageBean.ERROR,

viewBean.PASSWORD_KEY,”<LI class=’error’>”,”</LI>” %>

In this example, messages would only appear next to the input fields if the Message Bean contained messages of type ERROR and with location keys of viewBean.USERID_KEY or viewBean.PASSWORD_KEY. Other messages would likely be displayed elsewhere on the screen.

3.9 Working with the ResultHandler The default ResultHandler class that comes in Jade is a utility class that manages the work of taking the data from the backend and passing it on to the ResultBean and its sub components like ViewBean, MessageBean and StateBean. One must understand some of the design rationale behind the default implementation and if need be sub-class when one develops an application.

Jade attempts to construct the ResultBean via the ResultHandler while still in the Transaction Context if one exists, to assure that the data passed to the ResultBean is valid. However as a result of this, often in applications where Transaction Context is not an issue, it becomes cumbersome to move data from the back end to session.

3.9.1 Storing Data in Session with ResultHandler If you are familiar with the flow of Jade, you will understand that it is easy to RETRIEVE data from session before invoking a process object. Generally here is the flow:

1. From the servlet layer you get a Parameters object and a JadeSession object

2. In the action handler layer then, if need be you can retrieve some previously stored data from JadeSession and augment the current Parameters object.

3. One can then instantiate the ResultHandler and invoke the Process Object of choice, passing in the Parameters object and ResultHandler to the method of choice.

//action handler layer

public ResultBean execute(Parameters parms, JadeSession session)

{

ResultHandler handler = null;

ResultBean result = null;

try

{

//retrieve data from session

String userId = session.getValue(USERID_KEY);

//add it to the params

parms.addParameter(USERID_KEY, userId);

//create the result handler

Page 56: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 56

handler = new ResultHandler(parms);

//invoke the process

result = UserProcess.singleton().changePreferences(parms, handler);

}

catch(Exception ex)

{

result = handleException(ex);

}

}

Unfortunately, on the way back out, the default flow is not as staightforward. Let’s see the flow:

1. While in the Process Object, you add some data or objects to the ResultHandler using the addObject method.

2. This data is then passed on through a series of method invocations to the ViewBean where in its collectResults() method, it has access to all the data. Generally, most of the data is whatever is needed for the view. However, if there is some data that needs to be stored in session so that a subsequent request can have access to it, your only choice is to store the data you need on the ViewBean. (This is because outside of the ViewBean no other object has access to the data of the ResultHandler).

3. When you get back to the action handler layer after the execute() method has completed, you have access to the ResultBean that has been returned. You can navigate the ResultBean and from it retrieve the ViewBean and from that get the data you wanted and store it in session.

//sample process layer method

public ResultBean changePreferences(Parameters parms, ResultHandler handler)

{

try

{

//do something with the back end.

Collection preferences = ….

User user = ….

handler.addObject(USER_KEY, user);

handler.addObject(PREF_KEY, preferences);

handler.getResultBean();

}

catch(Exception ex)

{

handleException(ex);

}

}

Page 57: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 57

//view layer

public void collectResults(Parameters data)

{

//retrieve the data that was stored in the handler

User user = (User) data.getParameter(USER_KEY);

//now let’s say you want to store the prefs in session

//you have no choice but to save the prefs on the view bean

//and then add them to JadeSession when the execute returns

//in the action handler layer

Collection prefs = (Collection) data.getParameter(PREF_KEY);

}

//action handler layer

public ResultBean execute(Parameters parms, JadeSession session)

{

ResultHandler handler = null;

ResultBean result = null;

try

{

…//same as above

//invoke the process

result = UserProcess.singleton().changePreferences(parms, handler);

//now we need to store the prefs in Session

Collection prefs = result.getViewBean().getPrefs();

//assuming you created some method like that to get the preferences

session.putValue(PREF_KEY, prefs);

}

catch(Exception ex)

{

result = handleException(ex);

}

Page 58: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 58

}

To some people this may seem a very circumvented way. Moreover, someone may not want to store so much data on the ViewBean and then try to null it before the JSP is called.

To accommodate an easier way to handle storing data in JadeSession on the way out, in this release we have added a method to the ResultHandler API called getParameters(). Basically this method gives access to the Parameters object that ResultHandler uses to store data. So now you could just add the data to the ResultHandler and then do nothing in the ViewBean. When you got back to the ActionHandler layer, you could do:

public ResultBean execute(Parameters parms, JadeSession session)

{

ResultHandler handler = null;

ResultBean result = null;

try

{

…//same as above

//invoke the process

result = UserProcess.singleton().changePreferences(parms, handler);

//now we need to store the prefs in Session

Collection prefs = (Collection)

handler.getParameters().getParameter(PREF_KEY);

session.putValue(PREF_KEY, prefs);

}

catch(Exception ex)

{

result = handleException(ex);

}

}

This is a much cleaner solution and avoids doing anything in the ViewBean. Please note however, that if the data that you are trying to store in JadeSession has a transaction context when you store it, there is no guarantee that the data in session will be valid when you retrieve it. So make sure by the time you are in the ActionHandler layer, that your data is not transaction aware.

3.9.2 Storing Data in Session with a sub-class of ResultHandler Another way around the problem is to create your own subclass of the ResultHandler class and give it a method like getObject(String key) : Object. Then in the ActionHandler layer, always instantiate your own handler class instead of the default ResultHandler and use that to retrieve data from when the execute() method has completed.

Page 59: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 59

e.g.

public ResultBean execute(Parameters parms, JadeSession session)

{

XYZHandler handler = null;

ResultBean result = null;

try

{

…//same as above

handler = new XYZHandler(parms);

//invoke the process

result = UserProcess.singleton().changePreferences(parms, handler);

//now we need to store the prefs in Session

Collection prefs = (Collection)

handler.getObject(PREF_KEY);

session.putValue(PREF_KEY, prefs);

}

catch(Exception ex)

{

result = handleException(ex);

}

}

3.9.3 UNDO The ResultHandler in conjunction with the ResultBean framework and the JadeGatewayServlet has a feature called “UNDO”. This feature is a convenience feature that allows a developer to conveniently bring a user to the STATE in which they were prior to the current request, without any programming.

When a request is serviced using the JadeGatewayServlet, before the ResultBean is put on the request so that the JSP can access it, it is also stored in JadeSession with a key indicating that this was the previous state. When a subsequent request comes in and during the execution, if the developer wants to put the user in the STATE that he /she was before the request, they can invoke the getUndoResultBean() method on the ResultHandler and the JadeGatewayServlet will in turn retrieve the previous ResultBean from JadeSession and use that for the JSP.

NOTE: Be careful when using the UNDO feature. The UNDO is designed to take the user to the previous state. If for some reason, after the 1st request, the 2nd request does not have a Jade associated state with it, then when a 3rd request comes as a result of something happening on the 2nd request, the UNDO feature will take the user to the state of the application at the end of the 1st request! This is because the 2nd request was not mapped to a Jade application state. To avoid this problem, make sure even your static HTML pages have a Jade application state that they map to.

Page 60: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 60

3.9.3.1 Handling Form Data In conjunction with the UNDO feature one must there clearly understand how to deal with form data and how to send it back if required.

When the form data comes in, it is all stored in the incoming Parameters object. When executing a Process Object one may determine that the form data is invalid or data is missing and want to send the incoming data back to the screen. To do this, one must do the following:

1. Take the incoming Parameters object and add it to the ResultHandler using the addObject() method. Please note this adds this Parameters object to the INTERNAL Parameters object of the ResultHandler.

2. Code a ViewBean for the JSP on which the form was. In its collectResults() method one must remember that the Parameters object that the collectResults() method has as an argument is the INTERNAL Parameters object of the ResultHandler and NOT the incoming Parameters object. So first, you need to RETRIEVE the incoming Parameters object from this Parameters object and then from that Parameters object one by one you can add the data you need to the ViewBean so that it can recreate the FORM.

Here’s an example :

//process object layer

public ResultBean someProcessMethod(Parameters parms, ResultHandler handler)

{

try

{

//let’s assume this data is invalid or bad and we throw some exception

String x = parms.getParameterAsString(X_KEY);

}

catch(Exception ex)

{

//we now want to re-throw the data back on the page and send an error message

handler.addObject(PARAMETERS_KEY, parms);

handler.setMessage(“invalid x”);

handler.getResultBean();

}

}

//view bean collectResults() method

public void collectResults(Parameters parms)

{

//retrieve the form data parms object from the result handler parms object

Parameters formData = (Parameters) parms.getParameter(PARAMETERS_KEY);

Page 61: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 61

//get one of the parms

String x = formData.getParameterAsString(X_KEY);

//set it on the view bean

setX(x);

String y = formData.getParameterAsString(Y_KEY);

setY(y);

String z = formData.getParameterAsString(Z_KEY);

setZ(z);

}

3.10 Creating Process Objects Process Objects can be of any type and shape, they can be normal java objects, they can be implemented as singletons, they can be created and destroyed in each invocation and they can be EJB’s Session Beans. They can even be adapter classes to the actual workflow classes.

The main considerations are on performance, on transaction support and on threading issues, but mostly Process Objects are application specific.

In the examples provided with the framework the implementation of the Process Object followed the singleton pattern. This is not a requirement and different implementations can be used.

3.10.1 Transaction considerations The model suggested for transactions is the following:

Page 62: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 62

In this model the Business transaction is committed, and the Bean is created inside another transaction. This allows checks to be done by the first commit, which would not be possible without multiple transactions. For example, if the first Commit fails the Process Object can define a special State Bean to be set so that the user can be informed of the exception.

There are cases where one does not need two transactions, this is the case with read operations, in this case the read is successful or not so two transactions are not necessary.

3.11 Handling Exceptions Exception handling is generally application specific. Exceptions can be thrown programmatically when error conditions occur in the application or when runtime errors occur such as when a database connection is not established.

With the Java programming language, one generally has two choices when programming exception conditions. Either one can throw an exception or one can catch the exception and deal with the problem. The goal of the Jade Framework is to provide a basic level of exception handling to conditions that may occur in a J2EE web container environment, so that the application developer can concentrate on dealing with application specific errors that may occur.

In order to achieve this, the methods of the JadeBaseHttpServlet class in the framework catch and handle all the common exceptions that may occur in a J2EE web container environment. In addition to this, as a precautionary measure, the service() method of the JadeBaseHttpServlet catches Throwable, the super class of all exception classes, to handle any unforeseen problems.

Thus we see that the responsibility of handling exceptions specific to the application fall on the shoulders of the application developer. It is up to the application architect and developers to decide during design how exceptions are going to be handled and which layers of the application are going catch certain exceptions and which layers are going to throw exceptions.

Again, one then has to decide that if a particular layer is going to handle the exception, what is it going to do? An object in any particular layer can do any of the following:

Page 63: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 63

• Log the error condition and correct the error condition so that processing can continue

• Log the error condition and abrupt processing because the error was so critical.

In Jade, we do not go into the specifics of handling exceptions at the Process Object level and below. However, feel free to review the HBA and HBAM sample applications to see how we handled exception conditions.

However above the Process Object level, i.e. at the level of the ActionHandlers and Servlets, Jade offers some exception handling capabilities.

3.11.1 ActionHandler Level Exception Handling Depending on how you code your Process Objects, the methods of your Process Objects will throw certain exceptions. It is useful to use the ActionHandler layer as a place to catch such exceptions. This has two benefits – it avoids unnecessary exception handling in the Servlet layer and it gives the ActionHandler layer to assist in rectifying the problem if possible. One of the most common problems that may occur is that for some reason, the ResultBean returned may be null. If you do not handle this problem, the problem will show up when the JSP is accessed and things may get ugly. It may be therefore useful to check to see that a valid ResultBean is returned and if not, use the catch block to create a “dummy” ResultBean so that processing can at least continue. You may want to even set a message in this “dummy” ResultBean to notify the user that processing did not go as planned. Thus, as a piece of advice, make sure you have a try-catch block in the execute() method of every ActionHandler class you create and use it to assist in exception handling.

3.11.2 Servlet Level Exception Handling Depending on how you design your application, your Servlets may talk to ActionHandlers or may directly talk to Process Objects. If the Servlets talk directly to Process Objects, then the ideas explained in the section above will equally apply here. Since in this case there is no ActionHandler layer, the servlet may have to catch an exception that occurs an appropriately create a ResultBean to let things move on. There is one extra thing that the servlet can do that cannot be done in any of the other layers – launch the error page using the handleException() method. This ensures that the exception is logged and the error page is invoked. Depending on the severity of the error, the servlet can redirect to the user to the error page in the catch-block. Thus, as a piece of advice, have a try-catch block in the doGet or doPost of all your servlets and in the catch block, call the handleException() method.

NOTE: Jade provides a default error page. However, it is advisable to create a nice error page that is uniform with the application’s user interface to display to the user in the case of an error. You can configure Jade to show this page by editing the html.xml file under the jade\config\property directory and changing the following entry:

<html>

<html-key>html.errorPage.name</html-key>

<html-name>jade_error.html</html-name>

</html>

NOTE: Jade provides a default invalid session page. However, it is advisable to create a nice error page that is uniform with the application’s user interface to display to the user in the case of there is no valid session. You can configure Jade to show this page by editing the html.xml file under the jade\config\property directory and changing the following entry:

<html>

<html-key>html.invalidSessionPage.name</html-key>

<html-name>not_logged_in.html</html-name></html>

Page 64: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 64

NOTE: During development a developer may want to see the exceptions happening to help in debugging. To have the exception stack trace streamed to the browser instead of having to look in the log file every time, set the SITE DEBUG flag in the property.xml file under jade\config\property directory to TRUE. For production, set this value to FALSE.

3.11.3 JSP Level Exception Handling The goal of the Jade Framework is to provide a robust runtime environment for the application so that errors are minimum. Hopefully, by the time code reaches the JSP layer it is bug-free. However one can never be sure and so it is good to take precautions. JSP 1.0 provides a way to specify an error page as part of the page declaration in case of an error.

<%@ page extends = "com.ibm.ead4j.jade.jsp.BaseJSP" errorPage = “/web/itso_bank_error.jsp" %>

3.12 Logging Jade provides support for 2 kinds of logging and provides an API for creating a custom log writer if one wants to create a custom log. There are two logs generated by Jade:

• Tracing – This logs information during the bootstrap process to the console

• JadeLogyyyyMMdd – This file logs information during the lifetime of the application.

3.12.1 Simple Logging The simple logging features provided by Jade logs useful information in the jade.log file. A lot of what is to be logged is application-specific and depends on the developer. Jade provides APIs for logging information, warnings, errors and exceptions to the log file. Logging can be done at the servlet layer using the logging methods provided by the JadeBaseHttpServlet or in any other layer using ApplicationContext. Jade logs important information such as:

• URL request

• Parameters

• Session and Session ID

• Exceptions

3.12.2 Logging with Log4J Log4J is an open-source effort to develop a logging framework. Log4J provides sophisticated features for controlling the amount of logging to improve performance, log roll over and other features required of an enterprise-strength logging feature. For more details please go to http://jakarta.apache.org/log4j

To use Log4J in conjunction for Jade, you need to download the Jade Standard Extensions. Download the ead4j-ext.2.5.0.zip file from the EAD Portal site and add the VAJ solution in it to the workspace. This includes the latest version of Log4J in VAJ .dat format. Refer to the ead4j_bootstrap.properties file for some instructions on want to uncomment for Log4J support.

Page 65: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 65

4. Appendix – Utility Descriptions

4.1 Email The E-mail sender function in JADE 2.5 allows e-mail messages to be sent through an SMTP server. It is built upon the JavaMail 1.2 API. In order to run the e-mail sender, the following other components need to be installed:

1. JavaBeans Activation Framework (JAF), currently at version 1.01

2. JavaMail 1.2

The following features and data elements are supported:

1. Single or multiple recipients

2. Single or multiple copy recipients

3. Subject line

4. From

5. E-mail message body

6. File Attachments (single file)

The following three e-mail MIME types are supported for the e-mail message body:

1. text/plain

2. text/html

3. text/xml

Other MIME types may be usable, however they have not been tested.

Note: at the present time, the e-mail sender does not support mixed multi-part message MIME types (e.g. an e-mail consisting of an HTML part, RTF part, and WAV part).

4.1.1 Classes and mailConfig.xml File Description

4.1.1.1 Core classes The e-mail function makes use of the factory and singleton design patterns, and consists of two core classes:

1. EmailSenderFactory

2. EmailSender

Page 66: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 66

The EmailSenderFactory is responsible for returning a “named” EmailSender instance. Each named EmailSender instance has its own configuration -- including an implementation class name, MIME type, and SMTP hostname. The EmailSenderFactory maintains a hashmap of named EmailSender instances, which are defined in the mailConfig.xml configuration file. When a named EmailSender is requested, a new named EmailSender instance is created if one does not already exist. This design allows different JADE applications to use an EmailSender that meets its specific implementation, MIME type, and SMTP hostname requirements.

The EmailSender class performs the actual sending of the e-mail message and/or attachment (file data source). There are 24variations of the public sendMailMessage() method, with various signatures that support:

1. Single toList as a String, multiple toList as an array of Strings, and multiple toList as a vector of Strings

2. Single ccList as a String, multiple ccList as an array of Strings, and multiple ccList

4.1.1.2 Test Classes A test class is available to test out plain text, HTML, and XML e-mail messages with and without attachments:

1. EmailTester

The EmailTester class does the following:

1. Tests the loading of the mail configurations

2. Sends a plain text e-mail

3. Sends a plain text e-mail with a single plain text attachment

4. Sends an HTML e-mail message by itself (including embedded cascading style sheet classes)

5. Sends an HTML e-mail message (including embedded cascading style sheet classes) with a single plain text attachment

6. Sends an XML e-mail message by itself. The test message is simply an encoded mailConfig file.

7. Sends an XML e-mail message with a single plain text attachment

To run the tester, a command line argument is required - a string containing the e-mail recipient (e.g. [email protected])

The test class is located in the com.ibm.ead4j.jade.test package.

Page 67: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 67

4.1.1.3 mailConfig.xml File An XML configuration file, mailConfig.xml, is used to specify an e-mail configuration name and its associated:

1. Implementation class

2. Mime Type

3. SMTP Hostname

The following is a sample mailConfig.xml configuration file:

<?xml version="1.0" encoding="UTF-8"?><!-- ************************************************************************************** This document is used to define email connection information for an application. ** ** Element and Atrribute Definitions ** EmailSenderConfig - The element the contains all the configuration ** information as child elements. ** ConfigName - The name used to obtain a EmailSender instance. This ** name must be unique. ** ImplementationClass - The EmailSender implementation class to be used for ** this configuration. The same class type can be used for ** multiple configurations. ** MimeType - The Mime type to use for the body of the email. ** SMTPHost - The host name or address of the SMTP server to use to ** send emails for this configuration. *************************************************************************************** --><!-- Begin Embedded DTD --><!DOCTYPE EmailSenderConfiguration [<!ELEMENT EmailSenderConfiguration (EmailSenderConfig+) ><!ELEMENT EmailSenderConfig (ConfigName,ImplementationClass,MimeType,SMTPHost)><!ELEMENT ConfigName (#PCDATA)><!ELEMENT ImplementationClass (#PCDATA)><!ELEMENT MimeType (#PCDATA)><!ELEMENT SMTPHost (#PCDATA)>]><!-- End Embedded DTD --><EmailSenderConfiguration>

<EmailSenderConfig><ConfigName>Plain</ConfigName><ImplementationClass>com.ibm.ead4j.jade.email.EmailSender</ImplementationClass><MimeType>text/plain</MimeType><SMTPHost> d04nms23</SMTPHost>

</EmailSenderConfig><EmailSenderConfig>

<ConfigName>HTML</ConfigName><ImplementationClass>com.ibm.ead4j.jade.email.EmailSender</ImplementationClass><MimeType>text/html</MimeType><SMTPHost> d04nms23</SMTPHost>

</EmailSenderConfig><EmailSenderConfig>

<ConfigName>XML</ConfigName><ImplementationClass>com.ibm.ead4j.jade.email.EmailSender</ImplementationClass><MimeType>text/xml</MimeType><SMTPHost> d04nms23</SMTPHost>

</EmailSenderConfig></EmailSenderConfiguration>

The file above has three named configurations, “Plain”, “HTML”, and “XML”. The configuration names can be anything that you want.

Page 68: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 68

It should be noted that a Config Name must be unique across all web applications running in the same JADE environment.

4.1.1.4 Config File Location The email config file needs to be placed in the property directory or Jade or the application. Multiple copies of the file can be used each containing unique configurations.

4.1.2 Class Diagram EmailSenderFactory

isInitialized : boolean = falseXML_CONFIG_FILE_NAM E : St ring = "mailConfig.xml"ROOT_XML_TAG : String = "EmailSenderConfig"CONFIG_NAM E_XM L_TAG : String = "ConfigName"MIME_TYPE_XML_TAG : S tring = "MimeType"IMPL_CLASS_XML_TAG : String = "Implementat ionClass"SMTP_HOST_XML_TAG : String = "SMTPHost "IMPL_CLASS_CREATE_ERR_MSG : String = "Error instantiat ing Em ailSender implementation c lass: "

EmailSenderFactory()create(name : String) : com. ibm.ead4j.jade.email.EmailSendergetStatus() : Stringinitialize() : voidreinitialize() : voidcreateEmailSender(implClassName : String, smtpHos t : St ring, mimeType : String) : com.ibm.ead4j. jade.email.EmailSenderloadConfigurations() : voidparseDocument(root : javax.swing.tex t.Element ) : java.uti l.HashMap

(from em ai l)

Em a ilSende r

SM T P_ HOST _PROP : St ring = " ma il .sm tp .host"mi m eT yp e : S tri ng = nu ll

Em a ilSende r()set Con figura ti on (sm tpHost : St ring, m Type : St ring) : voi dge tHostProps() : java.ut i l.P rope rti esge tM im eT ype () : S trin gtoS tring () : S tr ingge tDebugM ode() : bo ol eange tRecipi en ts(toList : S tring[ ]) : ja va x.ma il .Add ress[]ge tRecipi en ts(recip ient : S tring ) : ja vax.ma il .Ad d ress[]ge tRecipi en ts(toList : ja va .u ti l.Ve ctor) : j avax.m ai l.A dd ress[]sen dMa il Message(toL ist : St ring[ ], f rom : S tri ng , sub ject : S tri ng , em ail Bo dy : St ring) : bo ole ansen dMa il Message(toRecip ie nts : ja vax.m a il.Ad dress[], ccRecipi en ts : ja vax. m ail .Address[ ], f rom : S tri ng, sub ject : S trin g, ema il Bo dy : String, fds : ja va x.act iva tion .Fi leDa taSource ) : bo ol eansen dMa il Message(to : S tri ng , f rom : S tri ng , sub ject : S tri ng , em ail Body : St rin g) : booleansen dMa il Message(to : S tri ng , f rom : S tri ng , sub ject : S tri ng , em ail Body : St rin g, fds : ja vax.act iva ti on. FileDa taS ource) : bool eansen dMa il Message(toL ist : ja va .ut i l.Vecto r, from : String, subject : Strin g, em a ilBody : S tri ng ) : boo leansen dMa il Message(toL ist : ja va .ut i l.Vecto r, ccLi st : ja va .u ti l. Vector, from : St ring, subject : St ring, ema ilB ody : S tri ng ) : bo o leansen dMa il Message(toL ist : ja va .ut i l.Vecto r, ccLi st : ja va .u ti l. Vector, from : St ring, subject : St ring, ema ilB ody : S tri ng , f ds : j avax.acti va tio n.F il eDataS ou rce) : boo leansen dMa il Message(toL ist : St ring[ ], ccL ist : St ring[] , f rom : S tri ng , sub ject : S tring , em ail Body : S t ring ) : boo leansen dMa il Message(toL ist : St ring[ ], ccL ist : St ring[] , f rom : S tri ng , sub ject : S tring , em ail Body : S t ring , fds : javax.acti va ti on.Fi leDa taSource) : bo ole ansen dMa il Message(toL ist : St ring[ ], cc : S tri ng , f rom : S tring , sub ject : S tring , em ail Body : St ring ) : b oo leansen dMa il Message(toL ist : St ring[ ], cc : S tri ng , f rom : S tring , sub ject : S tring , em ail Body : St ring , fd s : javax.acti va tion. Fil eDa taS ource) : booleansen dMa il Message(toL ist : St ring[ ], f rom : S tri ng , sub ject : S tri ng , em ail Bo dy : St ring, fds : ja vax.activation .FileDa taSo urce) : bool eansen dMa il Message(toL ist : St ring[ ], ccL ist : java. ut i l.Vecto r, from : S tring , sub ject : S tring , em ai lBody : St ri ng) : booleansen dMa il Message(toL ist : St ring[ ], ccL ist : java. ut i l.Vecto r, from : S tring , sub ject : S tring , em ai lBody : St ri ng, fds : ja vax.activati on .FileDa ta Sou rce ) : boo leansen dMa il Message(to : S tri ng , ccL ist : Str ing[] , f rom : S tring , sub ject : S tring , em ail Body : St ring ) : b oo leansen dMa il Message(to : S tri ng , ccL ist : Str ing[] , f rom : S tring , sub ject : S tring , em ail Body : St ring , fd s : javax.acti va tion. Fil eDa taS ource) : booleansen dMa il Message(to : S tri ng , cc : S tri ng , f rom : S tring , sub ject : S tring , e ma il Body : St ring) : boo leansen dMa il Message(to : S tri ng , cc : S tri ng , f rom : S tring , sub ject : S tring , e ma il Body : St ring, fds : ja vax.acti va tion.Fil eDat aSource) : booleansen dMa il Message(to : S tri ng , ccL ist : java.ut i l.V ecto r, from : S tring , sub ject : S tr ing , em ai lB ody : St ri ng) : boolea nsen dMa il Message(to : S tri ng , ccL ist : java.ut i l.V ecto r, from : S tring , sub ject : S tr ing , em ai lB ody : St ri ng, fds : ja va x.activati on .File Da taSource ) : bo o leansen dMa il Message(toL ist : ja va .ut i l.Vecto r, ccLi st : S tring [], from : S tring , sub ject : S tring , em ai lBody : St ri ng) : booleansen dMa il Message(toL ist : ja va .ut i l.Vecto r, ccLi st : S tring [], from : S tring , sub ject : S tring , em ai lBody : St ri ng, fds : ja vax.activati on .FileDa ta Sou rce ) : boo leansen dMa il Message(toL ist : ja va .ut i l.Vecto r, cc : Strin g, from : S tring , sub ject : S tr ing , em ai lB ody : St ri ng) : boolea nsen dMa il Message(toL ist : ja va .ut i l.Vecto r, cc : Strin g, from : S tring , sub ject : S tr ing , em ai lB ody : St ri ng, fds : ja va x.activati on .File Da taSource ) : bo o leansen dMa il Message(toL ist : ja va .ut i l.Vecto r, from : String, subject : Strin g, em a ilBody : S tri ng , fds : j avax.activat ion .Fil eDa ta Sou rce ) : boo lea n

(from email)

creates

4.1.3 Implementation Recommendations

4.1.3.1 Implementation Class The EmailSender class is extendable should additional functionality be required. To make use of a different implementation class, simply change the ImplementationClass XML element in the mailConfig.xml XML mail configuration file.

Page 69: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 69

The following sample code snippet shows how an EmailSender is obtained and then used to send an e-mail from within a JADE 2.1 application.

public ResultBean sendMail(Parameters parameters, ResultHandler handler)

{

ApplicationContext appContext = ApplicationContextFactory.singleton().getApplicationContext();

String basename = appContext.getConfigParameter(CTApplicationKeys.CORPTAX_MESSAGE_BASENAME);

// Get e-mail components from parameters object

String targetAddress = params.getParameterAsString(CTApplicationKeys.MAIL_ADDRESS);

String messageText = params.getParameterAsString(CTApplicationKeys.MAIL_TEXT);

String from = params.getParameterAsString(CTApplicationKeys.MAIL_FROM);

String from = params.getParameterAsString(CTApplicationKeys.MAIL_SUBJECT);

boolean rc = false;

try

{

EmailSender es = EmailSenderFactory.create(“Plain”);

rc = es.sendMailMessage(targetAddress, from, subject, messageText);

}

catch ( Exception e) {

LogContext.singleton().logException(e);

handler.setMessage(appContext.getMessage(basename, E_MAIL_FAILURE_MSG_KEY));

handler.setState(E_MAIL_FAILURE);

}

if (rc == true) {

handler.setState(E_MAIL_SENT_SUCCESSFULLY);

handler.setMessage(appContext.getMessage(basename, E_MAIL_SENT_SUCCESSFULLY_MSG_KEY));

}

Page 70: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 70

try

{

return handler.getResultBean();

}

catch ( ResultBeanException e) {

LogContext.singleton().logException(e);

handler.setMessage(appContext.getMessage(basename, SYSTEM_ERROR);

return handler.getUndoResultBean();

}

}

4.1.3.2 Create an Interface of Constants for Named Configurations To avoid hardcoding configuration names into the factory request for an EmailSender, use an interface to store the configuration names.

Ex. EmailSender es = EmailSenderFactory.create(E_MAIL_CONFIGURATION_1);

4.1.3.3 Store Message Constants in property.xml If your subject line, CC list, recipient list, attachment file name, or message body is constant, make them properties and store them in the property.xml file for the application, and look them up using the Application Context.

Example.

<property>

<key>CT_APP_SUBJECT_LINE</key><value>Claim your prize!</value>

</property><property>

<key>CT_APP_FROM</key><value>[email protected]</value>

</property><property>

<key>CT_APP_MESSAGE_LINE</key><value>You have won a great prize!</value>

</property>

<property><key>CT_APP_CC_LIST</key>

Page 71: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 71

<value>[email protected], [email protected], [email protected]</value></property>

4.1.4 Reinitializing the EmailSenderFactory If you need to reset the EmailSenderFactory to start using new or changed configurations, a utility method called reinitialize() is available.

EmailSenderFactory.reinitialize();

4.2 MultipartReader Updated Classes The MultipartReader and MultipartReaderImpl classes have been updated in this current version of JADE. In previous versions of JADE, the MultipartReader only read one file from the Multipart HTTP request, and represented the file as such. In this version, the MultipartReader can handle multiple upload files and other form field parameters. The MultipartReader stores parameters that it processes from the request into an internal hashmap. The uploaded files are represented by the UploadFile object, and other form field parameters are represented in a String key/value pair. The processed parameters can then be put back into the HTTP Request or the Parameters object or accessed directly from the MultipartReader.

4.2.1 MultipartReader Classes • MultipartReader – Interface that defines the functionality of the MultipartReader.

• MultipartReaderImpl – The implementation class of MultipartReader that handles the actual processing of the multipart http request. This class is defined in JADE’s property.xml file with the key from BootstrapKeys.JADE_UPLOAD_MULTIPART_KEY.

• MultipartReaderFactory – This factory class creates and returns the implementation of the MultipartReader Interface that is defined in JADE’s property.xml file with the key from BootstrapKeys.JADE_UPLOAD_MULTIPART_KEY.

• MultipartReaderInitializationException – This exception is thrown if the MultipartReaderFactory cannot find the correct MultipartReader implementation class.

• MultipartStreamReader – This class is used in the processing of a multipart http request.

• UploadFormFile – This interface defines the functionality of an uploaded file. When a file is processed by the MultipartReader, it is represented by this object.

• UploadFile – This class is the implementation of the UploadFormFile Interface. This object contains information about the uploaded file, including the original name of the file, content type, and location of the file on the server.

4.2.2 MultipartReader methods: • void initialize(javax.servlet.http.HttpServletRequest req) – This method is called by the

MultipartReaderFactory when creating and initializing the MultipartReaderImpl. The MultipartReader will use default values if the values aren’t specified in the property files. The keys for the MultipartReader values are located in the UploadKeys Interface. The default value and the key that the value can use in specified below. This method initializes: – Maximum upload file size (UPLOAD_FILE_MAX_SIZE , UPLOAD_FILE_MAX_SIZE_KEY) – Buffer size (UPLOAD_BUFFER_SIZE, UPLOAD_BUFFER_SIZE_KEY) – Upload directory (JADE class directory, UPLOAD_FILE_DIR_KEY)

• These values may also be set during run time (after the MultipartReader is initialized and before the processMultipart() is called) using the setter methods.

Page 72: EAD4J.jade Application Developer Handbook v2.6

Jade Framework Developer’s Handbook Tuesday, February 05, 2002

IBM Confidential 72

• void processMultipart() – This method handles the processing of the Multipart request. It will extract and save all uploaded files, and read all form field parameters from the request. It will store these parameters and references to the uploaded files into an internal HashMap.

• getParameterFromRequest() and getAllParametersFromRequest() allow access to the parameters that were extracted from the request.

• storeParametersInRequest() will take all the parameters that were extracted from the Multipart request and store them back into the Http request. This allows the parameters to be accessed from the Http request as they normally would.

• storeParametersInParameters() will take all the parameters that were extracted from the multipart request and store them in the JADE parameters object.

4.2.3 HTML for the Upload Process The following HTML is needed when doing a multi-part request:

<FORM ACTION="jadeUpload" ENCTYPE="multipart/form-data" METHOD=POST> <INPUT TYPE=”FILE” NAME="HBA_UPLOAD_APP1_KEY" VALUE="Browse" SIZE="57"> </FORM>

4.2.4 JADE Upload Process By using the JadeUploadServlet, the Multipart request will be parsed and put back into the request. Since the JadeUploadServlet extends the JadeGatewayServlet, the request will be processed as it normally would through the JadeGatewayServlet. Action Handlers will be able to access the uploaded files by retrieving the file from the Parameters object in the form of the UploadFile object. It may be accessed by the key that it was assigned to in the html form.

The MultipartReader can also be used in a custom servlet. The multipart request is processed in the same way, but a custom servlet may define exact actions to take.

4.2.5 Upload Security Security in a web application may be handled in many different ways. In a multipart request – it is not apparent what parameters the request contains until it is processed. If your security depends on the Jade Action Code – the multipart request must be processed first to find the action code. By it’s nature, the MultipartReader will automatically save the files being uploaded during processing. If your security check discovered that this action was not allowed, a possible solution is to delete the files that were saved to the server. (All uploaded files may be found by doing an “instance of” UploadFile object). A custom implementation of the MultipartReader can take other forms of security into account.