How Web Applications Work

Web applications generate dynamic HTML-based webpages accessed through a web browser. Since WebObjects applications are object-oriented and written in Java, your application generates webpages by creating instances of objects called web components.

A web component is a combination of a Java subclass of WOComponent and an HTML template. Web components can contain any standard HTML elements and components including Flash animations, QuickTime movies, JavaScript programs, and Java applets. Web components also support Cascading Style Sheets (CSS).

You add dynamic content to your webpages by adding special WebObjects elements with HTML counterparts—called dynamic elements—to your web components. Some dynamic elements don't have HTML counterparts and are just used to control the generation of content—for example, content that is conditional or iterative. Dynamic elements are translated into static HTML when responding to client browser requests.

You can use either WebObjects Builder or Direct to Web to construct web components. WebObjects Builder is a graphical tool for creating web components and binding dynamic elements to variables and methods in your application.

Direct to Web is a rapid prototyping tool that creates a working web application from a given EO model. You use the Web Assistant to change the content of Direct to Web components. You can also freeze pages—create and add web components to your project—and modify them using WebObjects Builder.

You should have a basic understanding of the architecture of a web application before customizing your web application. This section describes the architecture of web applications and explains how dynamic elements work within the context of the application's request-response loop. It contains a brief description of the sequence of methods invoked when processing a request and generating a response page. This section also explains how backtracking works in WebObjects.

This document does not explain how to use the various WebObjects tools. Read WebObjects Builder User Guide for the steps involved in creating forms and binding dynamic elements. Read WebObjects Direct to Web Guide for how to use Direct to Web.

Application Architecture

Not only can your web application generate dynamic content but you can present forms to the user allowing them to author content. You obtain input from users using HTML-based forms, buttons, and other dynamic elements. Connecting form elements to variables and methods in your web component is similar to binding other dynamic elements that just display content.

You create forms by placing dynamic elements into a standard form element in your web component. The web component generates HTML that web browsers can interpret and display. This process includes translating user-entered data or selections back into variables in your application. If you are programming web components, it helps to understand how web applications process user input.

WebObjects applications are event driven, but instead of responding to mouse and keyboard events, they respond to HTTP (Hypertext Transfer Protocol) requests. The application receives an HTTP request for an action, responds to it, and then waits for the next request. The application continues to respond to requests until it terminates. The main loop that handles these requests is called the request-response loop.

Inside the request-response loop, WebObjects fills in the content of dynamic elements when the page needs to be generated in response to a request. The information your applications publish can reside in a database or other data-storage medium or it can be generated at the time a page is accessed. The pages are also highly interactive—you can fully specify the way the user navigates through them and what data they can view and modify.

Figure 1 shows a WebObjects-based website. Again, the request (in the form of a URL) originates from a web browser. The web server detects that the request should be handled by a WebObjects application and passes the request to an HTTP adaptor. The adaptor packages the incoming request in a form the WebObjects application can understand and forwards it to the application. Based upon web components you define and the relevant data from the data store, the application generates a webpage that it passes back through the adaptor to the web server. The web server sends the page to the web browser, which renders it.

This type of WebObjects application is referred to as a web application, since the result is a series of dynamically generated HTML webpages.

Figure 1  A dynamic publishing website
A dynamic publishing website

Request-Response Loop

Each action taken by a user is communicated to your application via the web server and the WebObjects adaptor. All the pertinent details of the user’s action—the contents of text fields, the state of radio buttons and checkboxes, and the selections in pop-up menus—as well as information about the session and the button or link activated is encoded in the HTTP request.

The request is decoded by the action of the WebObjects adaptor and default application behavior. This decoding process, which culminates in the generation of a response page to be returned to the web browser, constitutes the request-response loop. Figure 2 shows the sequence of messages invoked when processing a request.

Figure 2  The request-response loop
The request-response loop

WebObjects has two request-processing models: component actions and direct actions.

When developing an application, you are not restricted to one request-processing model. Applications can use the model most appropriate to implement specific features. Component actions are generally useful in web applications with interconnected components; however, they do not give the user a great deal of control over an application’s flow. For example, a user cannot directly execute a method defined in the Java source file of a web component. Direct actions, on the other hand, are better suited at providing users such access. For example, using the appropriate URL, users can execute specific methods of an application.

Refer to the API documentation for the WODirectAction class in WebObjects 5.3 Reference. This article explains component actions in more detail.

Component Action URLs

When you deploy a web application and access it from a web browser, the URL displayed by the browser has a specific format that identifies the web application, page, session, context, and even the element. Figure 3 shows the parts of the URL. The URL contains all the information necessary for an application to reconstruct the state of the session and web components that were last generated for a given client. Listing 1 shows an example of a component action URL.

Figure 3  Structure of a component action URL
Structure of a component action URL

Listing 1  Example of a component action URL

http://foo.com:49663/cgi-bin/WebObjects/TimeDisplay.woa/wo/NDdW3uF2xRVjvbXUgRCVM/0.5

Request-Response Loop Messages

Table 1 lists the phases of the request-response process. Table 2 shows the order in which the methods involved are invoked. The process is explained in detail in Processing the Request and Generating the Response. The primary objects that receive messages from the request-response loop are the application, session, and web component objects.

The application object is an instance of Application where Application is a subclass of WOApplication. A session object is an instance of Session where Session is a subclass of WOSession. An instance of Application is created when your application launches, and an instance of Session is created for each initial user. Note that sessions may time out. You can configure the time out duration when deploying an application.

If you select one of the web applications templates in Xcode when creating a project, Application and Session classes are automatically added to your project. Read Creating Projects for how to create a WebObjects Xcode project.

Table 1  Request-response processing phases

Phase

Method

Description

Awake

public void awake()

The application, session, and component objects are awakened. Custom initialization logic can be added in this phase.

Sync

public void takeValuesFromRequest (WORequest, WOContext)

Form data is read into the instance variables the WebObjects elements are bound to. Key-value coding set methods are invoked.

Action

public WOActionResults invokeAction (WORequest, WOContext)

The action the user triggered—with a link or a submit button—is performed. The action could create a new page.

Response

public void appendToResponse (WOResponse, WOContext)

The response page is generated. The form elements’ contents are set to the values stored in the instance variables the WebObjects elements are bound to. Key-value coding accessor methods are invoked.

Sleep

public void sleep()

The application, session, and component objects are put to sleep. Custom deactivation logic can be added in this phase.

Table 2  Request-response processing timeline

Application

Session

Component

awake

awake

awake

takeValuesFromRequest

takeValuesFromRequest

takeValuesFromRequest

Set methods invoked.

invokeAction

invokeAction

invokeAction

appendToResponse

appendToResponse

appendToResponse

Accessor methods invoked.

Response page generated.

sleep

sleep

sleep

Processing the Request

Request processing takes place in three stages: awake, sync, and action.

Generating the Response

After the form values are gathered and the action method is invoked, the application creates a response page. This is the web component returned by the action method. The response-generation process has two phases: response and sleep.

Backtracking Cache

WebObjects supports the use of a web browser’s Back button by keeping a cache of recently viewed pages on the server. This process is called backtracking. By default, a cache is configured to hold 30 pages per session, but you can customize it to meet your needs. To change the default size of the cache, add code to the Application class’s constructor. For example, to change the page cache size to 45 pages, you add this code line:

setPageCacheSize(45);

When a response page is generated, it and its state information are added to the cache. That way, when the user clicks the browser’s Back button, WebObjects can retrieve the correct web component and its state.

For backtracking to work properly with dynamic data, a web browser’s own cache must be disabled, so that all page requests go to the web server and, therefore, your application. You can do this by adding this code to the Application class’s constructor method:

setPageRefreshOnBacktrackEnabled(true);

When the cache becomes full, the oldest page in it is discarded to make room to store a new page. When the user backtracks past the oldest page in the cache, WebObjects alerts the user with a special webpage.

For more information on backtracking, read Backtracking and Cache Management.