Skip Headers
Oracle® SOA Suite Developer's Guide
10g (10.1.3.1.0)

Part Number B28764-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

9.1 Introduction to Developing a Web Application in an SOA System

Building web applications that will be part of an SOA system is very similar to building standalone web applications. However, it is likely that instead of communicating directly with data sources (for example, binding to business objects directly), the application will rely on web services to provide data. This chapter discusses how to create both a web application that accesses data directly, as well as one that uses a web service to access data.

Oracle ADF is an end-to-end application framework that builds on J2EE standards and open-source technologies to simplify and accelerate implementing service-oriented applications. In line with community best practices, applications you build using Oracle ADF achieve a clean separation of business logic, page navigation, and user interface by adhering to a model, view, controller architecture. As shown in Figure 9-1, in an MVC architecture:

Figure 9-1 MVC Architecture Cleanly Separates UI, Business Logic and Page Navigation

Image shows MVC architecture

9.1.1 View Layer Technologies Supported

In the view layer of your application, where you design the web user interface, you can develop using either classic JavaServer Pages (JSP) or the latest JavaServer Faces (JSF) standard. You work in JDeveloper with a WYSIWYG visual designer and drag-and-drop data binding.

The SOADEMO-CLIENT application is built on the JSF standard, using the Oracle ADF Faces library. While the JSF reference implementation provides a bare-bones set of basic UI components that includes basic HTML input field types and a simple table display, the ADF Faces library works with the ADF Model layer to provide rich functionality, including:

  • More sophisticated table model: Tables are a critical element of enterprise application UIs. By default, JSF doesn't support paging or sorting in tables. The ADF Faces table and the ADF Model table binding cooperate to display pageable, editable, or read-only, tables with sorting on any column.

  • Key-based current selection tracking: One of the most common tasks of web user interfaces is presenting lists of information and allowing the user either to scroll through them or to select one or more entries in the list. The ADF Model iterator binding simplifies tracking the selected row in a robust way, using row keys instead of relying on positional indicators that can change when data is refreshed and positions have changed. In concert with the ADF Faces table and multiselection components, it's easy to work with single or multiple selections, and build screens that navigate master-detail information.

  • More flexible models for common UI components: By default, JSF supports binding a checkbox only to boolean properties. ADF Model adds the ability to map the checkbox to any combination of true or valid values your data may present. The valid values for the list can come from any data collection in a data control and the list can perform updates or be used for row navigation, depending on your needs. The ADF Model list binding also makes null-handling easy by optionally adding a translatable "<No Selection>" choice to the list.

9.1.2 Business Services Technologies Supported by ADF Model

In the model layer, Oracle ADF Model implements the JSR-227 service abstraction called the data control and provides out-of-the-box data control implementations for the most common business service technologies. Whichever ones you employ, JDeveloper and Oracle ADF work together to provide you a declarative, drag-and-drop data binding experience as you build your user interfaces. Supported technologies include:

  • Enterprise JavaBeans (EJB) session beans: Since most J2EE applications require transactional services, EJB session beans are a logical choice because they offer declarative transaction control. Behind the EJB session bean facade for your business service, you use plain old Java objects (POJOs) or EJB entity beans to represent your business domain objects. JDeveloper offers integrated support for creating EJB session beans, generating initial session facade implementations, and creating either Java classes or entity beans. You can also use Oracle TopLink in JDeveloper to configure the object-relational mapping of these classes.

  • JavaBeans: You can easily work with any Java-based service classes as well, including the ability to leverage Oracle TopLink mapping if needed.

  • Web services: When the services your application requires expose standard web services interfaces, just supply Oracle ADF with the URL to the relevant Web Services Description Language (WSDL) for the service endpoints and begin building user interfaces that interact with them and present their results.

  • XML: If your application needs to interact with XML or comma-separated values (CSV) data that is not exposed as a web service, this is easy to accomplish, too. Just supply the provider URL and optional parameters and you can begin to work with the data. This enables the incorporation of Representational State Software (REST) style services.

  • ADF application modules: These service classes are a feature of the ADF Business Components module, and expose an updateable dataset of SQL query results with automatic business rules enforcement.

9.1.3 Declarative Development with Oracle ADF and JavaServer Faces

JavaServer Faces simplifies building web user interfaces by introducing web UI components that have attributes, events, and a consistent runtime API. You assemble web pages from libraries of off-the-shelf, data-aware components that adhere to the JSF standard.

In JSF you use a simple expression language to work with the information you want to present. Example expressions look like #{UserList.selectedUsers} to reference a set of selected users, #{user.name} to reference a particular user's name, or #{user.role == 'manager'} to evaluate whether a user is a manager or not. At runtime, a generic expression evaluator returns the List, String, and boolean value of these respective expressions, automating access to the individual objects and their properties without requiring code.

At runtime, the value of a JSF UI component is determined by its value attribute. While a component can have static text as its value, typically the value attribute will contain an EL expression that the runtime infrastructure evaluates to determine what data to display. For example, an outputText component that displays the name of the currently logged-in user might have its value attribute set to the expression #{UserInfo.name}.

Since any attribute of a component can be assigned a value using an EL expression, it's easy to build dynamic, data-driven user interfaces. For example, you can conditionally hide a component using a boolean-valued expression. A panel box on the cart page displays a message, but only when the cart is empty, using the expression #{empty (Shopping_Cart.itemList) ? true : false} for the panel box's rendered attribute. If the item list in the object named Shopping_Cart is empty, the rendered attribute evaluates to false and the component disappears from the page.

JDeveloper allows you to build complex expressions using a declarative tool, as shown in Figure 9-2.

Figure 9-2 The JDeveloper Expression Builder

EL Expression Builder in JDeveloper

To simplify maintenance of controller-layer application logic, JSF offers a declarative object creation mechanism. To use it, you configure the Java objects you need to use in a JSF faces-config.xml file. These objects are known as managed beans since they have properties that follow the JavaBeans specification and since the JSF runtime manages instantiating them on demand when any EL expression references them for the first time. JSF also offers a declarative mechanism to set the properties of these beans as they are first created. Managed beans can have managed properties whose runtime value is assigned by the JSF runtime based on a developer-supplied EL expression. Managed properties can depend on other beans that, in turn, also have managed properties of their own, and the JSF runtime will guarantee that the "tree" of related beans is created in the proper order.

Request-scoped managed beans that are tightly related to a given page are known colloquially as backing beans, since they support the page at runtime with properties and methods. The relationship between a UI component in the page and the backing bean properties and methods is established by EL expressions in a JSF page for the appropriate attributes of the component. For example:

  • value="#{expr}"

    References a property with data to display or modify

  • action="#{expr}"

    References a method to handle events

  • binding="#{expr}"

    References a property holding a corresponding instance of the UI component that you need to manipulate programmatically — show/hide, change color, and so on

Managed beans that aren't playing the role of a page's backing bean can be thought of as "application logic beans." They contain code and properties that are not specific to a single page. While not restricted to this purpose, these type of managed beans sometimes function as business service wrappers to cache method results in the controller layer beyond a single request and to centralize pre- or post-processing of business service methods that might be used from multiple pages.

In addition to using managed beans, you can also write application code in a PhaseListener class to augment any of the standard processing phases involved in handling a request for a JSF page. These standard steps that the JSF runtime goes through for each page are known as the "lifecycle" of the page. Most real-world JSF applications will end up customizing the lifecycle by implementing a custom phase listener of some kind, typically in order to perform tasks like preparing model data for rendering when a page initially displays.

9.1.3.1 Declarative Page Navigation with JSF

In addition to declarative UI design, JSF also provides a mechanism to declaratively define page navigation rules. Developers define these rules by specifying logical names for the legal navigation "outcomes" of a user's interaction with a page. For example, while on the browseItems page of the SOADEMO-CLIENT application, an end user may interact with the page by selecting an item and clicking the View Details button. The logical navigation outcome of this interaction is to go to the selectItem page to see more details. On the selectItem page, an end user might want to return to the browseItems page. As shown in Figure 9-3, you might create names like details and return to describe the outcome. The navigation rule information is saved along with other configuration information in the faces-config.xml file, and at runtime JSF handles the page navigation based on these logical outcome names.

Figure 9-3 Visualizing JSF Navigation Rules in JDeveloper's Page Flow Diagram

Image of Page Flow diagram

9.1.3.2 Declarative Data Binding with Oracle ADF Model Layer

The Oracle ADF Model layer uses XML configuration files to drive generic data binding features. It implements the two concepts in JSR-227 that enable decoupling the user interface technology from the business service implementation: data controls and declarative bindings.

Data controls abstract the implementation technology of a business service by using standard metadata interfaces to describe the service's operations and data collections, including information about the properties, methods, and types involved. At design time, visual tools like JDeveloper can leverage the standard service metadata to simplify binding UI components to any data control operation or data collection. At runtime, the generic Oracle ADF Model layer reads the information describing your data controls and bindings from appropriate XML files and implements the two-way "wiring" that connects your user interface to your business service.

Declarative bindings abstract the details of accessing data from data collections in a data control and of invoking its operations. There are three basic kinds of declarative binding objects that automate the key aspects of data binding that all enterprise applications require:

  • Iterator bindings to bind to an iterator that tracks the current row in a data collection

  • Value bindings to connect UI components to attributes in a data collection

  • Action bindings to invoke custom or built-it operations on a data control or its data collections

Iterator bindings simplify building user interfaces that allow scrolling and paging through collections of data and drilling-down from summary to detail information. UI components that display data use value bindings. Value bindings range from the most basic variety that work with a simple text field to more sophisticated list, table, and tree bindings that support the additional needs of list, table, and tree UI controls. An action binding is used by UI components like hyperlinks or buttons to invoke built-in or custom operations on data collections or a data control without writing code.

The group of bindings supporting the UI components on a page are described in a page-specific XML file called the page definition file. Generic bean factories provided by ADF Model use this file at runtime to instantiate the page's bindings. These bindings are held in a request-scoped map called the binding container, accessible during each page request using the EL expression #{bindings}. This expression always evaluates to the binding container for the current page. Figure 9-4 shows how EL value binding expressions relate the UI components in a page to the binding objects in the binding container.

Figure 9-4 Bindings in the Binding Container Are EL Accessible at Runtime

Bindings in binding container are EL accessible at runtime

Figure 9-5 illustrates the architecture of a JSF application when the application also leverages the ADF Model for declarative data binding. When you combine Oracle ADF Model with JavaServer Faces, it saves you from having to write a lot of the typical managed bean code that would be required for real-world applications. In fact, many pages you build won't require a "backing bean" at all, unless you perform programmatic controller logic that can't be handled by a built-in action or service method invocation (which ADF Model can do without code for you). You can also do away with any application logic beans that wrap your business service, since the ADF Model's data control implements this functionality for you. And finally, you can often avoid the need to write any custom JSF phase listeners because ADF Model offers a generic JSF phase listener that performs most of the common operations you need in a declarative way based on information in your page definition metadata.

Figure 9-5 Architecture of a JSF Application Using ADF Model Data Binding

JSF application Architecture using ADF Model data binding

The core module in the framework is Oracle ADF Model, a declarative data binding facility that implements the JSR-227 specification. The Oracle ADF Model layer enables a unified approach to bind any user interface to any business service with no code.

9.1.4 Building a Web Application

The typical development process of building an Oracle ADF application starts with creating the services that will supply the data. For example, the SOADEMO-CLIENT application uses Java Persistence API (JPA) entities to map to the products in the PRODUCT database table. It also uses an EJB session bean to create the service used to aggregate and present the data. Once these are created, you can generate data controls that you can then use to create the web client. For example, the ProductsFacadeLocal data control in the SOADEMO-CLIENT application allows developers to drag and drop results of standard CRUD methods run on the session bean as various ADF Faces components. For more information about creating a data control for EJBs, see Section 4.7, "Exposing Services with ADF Data Controls".

There may also be instances when the web client accesses data through a web service, as the SOADEMO-CLIENT does when using the CustomerService web service to create a customer. You can also create data controls from the web service, or in some cases, you may need to work with the web service directly, without using the ADF Model layer. For more information about creating data controls for web services, see Section 5.3.3, "How to Create a Data Control From a Web Service". For more information about when you may need to work directly with a web service, see Section 9.6.3, "How to Invoke a Service Using a Backing Bean".

Once data controls are created, you create the pages and the navigation between them using the JSF navigation diagram. For more information, see Section 9.3, "Creating a Web Page". Once the navigation is set, you can begin to add complex capabilities to your pages. You may find that a page will need to manipulate components, or will require additional logic. When that is the case, you can create a backing bean for the page. For more information, see Section 9.4, "Creating and Using a Backing Bean for a Web Page".

Web pages typically fall into two categories: those used to display data and those used to collect data. In the SOADEMO-CLIENT application, the ProductsFacadeLocal data control was used to declaratively create the table that displays products on the browseItems JSP, using ADF data binding. For more information, see Section 9.5, "Displaying Collection and Detail Data Using ADF Data Binding".

The Registration page collects user information and sends it to the external customer service application that is published as the CustomerService web service. This page does not use ADF for data binding. Instead, input text fields were created, and the page's corresponding backing bean handles the binding of entered data. For more information, see Section 9.6, "Collecting Data for Use by a Web Service". This section details both how to use an ADF data control with a web service, and how to invoke a web service manually from a backing bean.