Chris Schalk's J2EE Weblog
Chris Schalk's J2EE Weblog
Chris Schalk's Weblog on J2EE Web Development
All | General | Java | JSF | Oracle

20051231 Saturday December 31, 2005

Anatomy of an AJAX Transaction

In case you've heard all the AJAX hype but still haven't seen a good, simple technical explanation of what AJAX really is.. look no further.

As a small New Years gift, here is a brief write up on the core technology that makes AJAX possible.

In order to present AJAX in its purest form, I'll just provide a basic AJAX only example without mixing it with other technologies such as JSF, JSP etc. (I'll show that later..)

First of all, is AJAX New?

Not really. Remote Javascript, of which AJAX is one example of, has garnered the most attention as of late, provides the ability to interact with a server with XML data. AJAX is possible because of the leading browsers now offering objects that can make independent XML HTTP requests. Internet Explorer 5 and later offer an XMLHTTP object while Mozilla based browers provide an XMLHttpRequest object. Both of these objects offer essentially the same ability to request XML data from a server and process the data in a similar fashion. The server-side AJAX component can be in any technology providing XML can be delivered dynamically. Any dynamic Web technology ranging from PHP to servlets can serve as an AJAX server.

One of the drawbacks to Remote Javascript and AJAX is that it forces the page author (the person designing the final page) to develop a fair amount of Javascript code that manages the XMLHTTP interactions. Fortunately this is where JavaServer Faces provides a solution and makes AJAX very easy to use.

AJAX Under The Hood

Before reviewing more advanced examples of AJAX enabled JSF components, it is useful to full understand the core AJAX architecture involved in an AJAX client-server transaction.

AJAX is possible providing the two core technologies are present:

  • A Javascript enabled browser that supports either XMLHTTP or XMLHttpRequest objects.
  • An HTTP Server technology that can respond in XML.

Since the popular browsers support Javascript and the necessary XMLHTTP request objects and almost any Web server technology can generate XML(or any markup), the core AJAX technology is widely available.

An AJAX application in its simplest form is essentially a standard HTML user interface with Javascript functions to interact with an HTTP server that can generate XML dynamically. Any dynamic Web technology ranging from CGI to servlets even including JavaServer Faces as we’ll review later, can serve as a server-side AJAX technology.

The key elements of a core AJAX application are:

  • An HTML page that contains:
    • UI elements that interact with AJAX Javascript functions
    • Javascript Functions that interact with AJAX server.
  • A server-side Web technology that can process HTTP requests and respond in XML markup.

Reviewing the key elements, we have an HTML user interface with elements such as an input field, a button or anything that can be linked to Javascript. For example a button could fire a Javascript function when pressed, or for even more subtle usage an input field could fire a Javascript function as the user types into the field. For this an “onkeyup=” could be set to the value of the Javascript function to process the data in the input field. For example the input field “searchField” will call the Javascript function “lookup( )” when an onkeyup events occur (i.e. during typing).

<input type="text" id="searchField" size="20" onkeyup="lookup('searchField');">

In addition to responding to user interface interactions (like typing), AJAX Javascript functions they can operate independently on their own timers. (An AJAX autosave feature can be implemented using this approach.)

How to issue an XML HTTP Request

Now that we’ve reviewed how the AJAX Javascript code can be invoked, let’s review the actual code in Javascript that can issue an XML HTTP request:

 if (window.XMLHttpRequest) {
  req = new XMLHttpRequest();
}
else if (window.ActiveXObject) {
  req = new ActiveXObject("Microsoft.XMLHTTP");
}

This code snippet allows both major browser families (Internet Explorer and Mozilla/Safari) to make independent HTTP requests to servers. This code first checks to see if the browser supports either of the supported XMLHTTP objects and then instantiates one.

Once an XMLHttpRequest (or Microsoft’s XMLHTTP) object has been instantiated, it can be operated on in exactly the same manner.

To initialize a connection to a server, the open method is used:

req.open("GET", url, true);

The first argument is the HTTP method (GET or POST). The second argument is the URL of the server (or form action is using a POST) and the third argument when true denotes whether the call should be made asynchronously (The “A” in AJAX). This means that the browser can continue doing other things while the request is being fulfilled. A false value in the open method denotes a non-asynchronous or serial processing. This is not recommended, since your browser will cease operations until the response has been returned.

After initializing a connection using open, the onreadystatechange call is made (only for asynchronous calls). This registers a callback function, which will be invoked once the request is complete:

req.onreadystatechange = processXMLResponse;

The function processXMLResponse( ), which processes the XML response, is invoked when the request is fulfilled. A callback function can also declared inline in the onreadystatechange statement:

req.onreadystatechange = processXMLResponse() {

   // process request

};

Any header content can also be specified using req.setRequestHeader. Such as:

req.setRequestHeader(“Cookie”, “someKey=true”);

Once the XMLHTTP request object (req) has been fully initialized, initiating a call to the server can be done using send( ):

req.send(null);

For GET requests, a null value or empty string “” is used.

POST requests contain a string argument with form data. They also require the Content-Type to be set in the header of the request. The following two lines show how to perform a AJAX POST request.:

req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded";

req.send(“[email protected]”);

The callback function, which is called once the request has been fulfilled, usually has some code to make sure the request has not error-ed out. This can be accomplished by checking the readyState as well as the overall status of the HTTP request. (A readystate of 4 means the XMLHTTP request is complete and 200 means it was a success (as opposed to 404 etc..)

function processXMLResponse() {

    if (xmlreq.readyState == 4) {

        if (xmlreq.status == 200) {

          // Process the XML response…

        }

    }

}

Processing the XML response is done using standard Javascript DOM methods. For example to extract the employee name from the incoming XML stream:

<employee>

    Chris

</employee>

one can use the following:

var name = req.responseXML.getElementsByTagName("employee")[0];

Parsing more complex XML involves iterating through the elements using code such as:

for (i=0;i<elements.length;i++) {
  for (j=0;j<elements[i].childNodes.length;j++) {
    var ElementData =   elements[i].childNodes[j].firstChild.nodeValue;

  }

}

How JSF can enable AJAX

JavaServer Faces and its component centric architecture solves the inherent difficulties of AJAX by allowing the Javascript and the embedded AJAX “plumbing” to be completely handled by the JSF component. The JSF page author need not even be concerned about the AJAX interactions between the client and the server. They just use the AJAX enabled JSF component as any other JSF component and it just does its job and provides a richer experience.

I'll be posting some examples of how JSF and AJAX can work together in the new year so that the end result is a rich internet application which is very easy to build. Stay tuned! :)

( Dec 31 2005, 06:53:25 PM PST ) Permalink Comments [5]

What JSF Components do you use?

Having been working with Faces for a while now, I've become fairly familiar with a certain set of custom JSF components with the obvious ones being MyFaces and Oracle's ADF Faces. However I'm curious to know what other JSF components people have been experimenting with?

Also, do you see a current void that today's JSF component libraries still lack a solid solution for?

Personally I think JSF components can still mature some more to further enable non Java expert page authors the ability to easily construct a Web app without requiring a lot of custom Java code to complete the app.

So what components do you use?

What do you think is still lacking?

( Dec 31 2005, 06:10:07 PM PST ) Permalink Comments [9]

20051126 Saturday November 26, 2005

Check out my Podcast on JSF, JDeveloper, ADF Faces

Hey Folks,

Recently I recorded a Podcast for Oracle Technology Network (OTN) Podcast series at:

http://www.oracle.com/technology/syndication/techcasts/index.html

In this Podcast chat about various JSF related topics and Oracle's support of them.. Including JDeveloper and JSF, Oracle's ADF Faces and how it relates to the overall Oracle ADF framework.

Apologies that my voice is a little hard to hear.. The mic was not as close as it should've been.. :)

Here's the direct link:

http://presenter.oracle.com/podcasts/otn/4375634.mp3

( Nov 26 2005, 07:30:27 PM PST ) Permalink Comments [0]

20051123 Wednesday November 23, 2005

Example ADF Faces Skin Posted

Here is a custom skin that I built for an upcoming ADF Faces demo application. It is called "indigo_orange" (for lack of a better name!)

Requirements: This skin was built and tested with JDeveloper 10.1.3 EA 1.

You can download this skin from:

http://www.orablogs.com/cschalk/samples/indigo_orange.zip

To install this skin into your ADF Faces App:

Unzip indigo_orange.zip into a temporary location. Read the "readme.txt" file. It has instructions on where to copy the files to.

Here's the contents of the readme:

To use this skin you must do the following:

1. Add the provided or edit your existing adf-faces-config.xml to include an entry for the indigo_orange skin. The adf-faces-config.xml should reside the same directory as your faces-config.xml (WEB-INF).

2. Copy the provided adf-faces-skins.xml to your WEB-INF location. This file sets the renderkit and provides an actual location of your indigo_orange.css file.

3. Copy the entire directory "/skins" to your reside under your webapp's HtmlRoot. Note: You can later add multiple skins to this directory.

For further documentation on the named styles which are customizable, consult the document: documentation/adf-faces-skins-doc.xml Also, example button images which are not used in this skin are provided in indigo_orange/example_button_images.

Have fun, and let me know if you get stuck!

-Chris

( Nov 23 2005, 12:15:53 PM PST ) Permalink Comments [15]

20051120 Sunday November 20, 2005

Disabling ADF Faces content compression

If you've experimented with ADF Faces enough to observe the generated output from the components you'll notice that the output is compressed down to a minimal form. While this improves overall app performance, it can make debugging an app, especially if you are changing the look and feel with a custom skin (See my previous posting on custom ADF Faces skins).

for example the output comes in a somewhat cryptic form such as:

<td class="x14"> | </td>

as opposed to:

<td class="af_menuBar_separator"> | </td>

Fortunately it is possible to turn off the compression by providing a small bit of code in the web.xml. By entering the following into your web.xml, the compression will be turned off..

<context-param>
<param-name>
oracle.adfinternal.view.faces.DISABLE_CONTENT_COMPRESSION
</param-name>
<param-value>true</param-value>
</context-param>

By the way, I just completed a custom skin for a demo application. I can post it if there is interest. :)

( Nov 20 2005, 05:03:08 PM PST ) Permalink Comments [6]

20051101 Tuesday November 01, 2005

What are your JSF pet peeves?

Having worked with JSF since its inception I feel that it offers a robust, thorough technology for building J2EE Web interfaces, however I do find some areas that still tend to be probably a little more difficult than they probably should be..

If you've worked with Faces, you may have your own pet peeves as well.

In short, some of the areas that I think can still be simplified a bit to start with are:

- Building custom UI components

- Security (actually this is for J2EE in general)

- Centralized look and feel (skinning)

- Internationalization

Before continuing on, I'd be curious to hear what your pet peeves are with JSF..

Feel free to comment and I'll explain further what I mean in these areas..

-Chris

p.s. Sorry for not posting much this month, I've been busy with jury duty! Such fun....

( Nov 01 2005, 10:26:45 AM PST ) Permalink Comments [10]

20051015 Saturday October 15, 2005

JSF: Getting the Right Mixture of Components and Markup

Having worked on generic Faces support in JDeveloper as well as with the ADF Faces team at Oracle, I've notice slightly different approaches to how to build JSF applications.

One approach tends to focus on a highly component centric approach where your pages are essentially 95% to 100% filled purely with JSF components. The ADF Faces team seems very comfortable with this approach since their previous experience with UIX was pretty much a purely component driven Web development experience. The other approach tends to be more markup (usually HTML) centric where a majority of the page is still markup and components are used only when absolutely necessary..

To better illustrate the different approaches, here are two code examples:

A component centric page could have the following structure:

<f:view>
<h:form>
<foo:MyCustomPageLayoutComponent>
<foo:MyPageBanner />
<foo:MyPageSubRegionComponent1>
<h:inputText><h:outputLabel>
</foo:MyPageSubRegionComponent1>
<foo:MyPageSubRegionComponent2>
<h:outputText />
</foo:MyPageSubRegionComponent2>
</foo:MyCustomPageLayoutComponent>
</h:form>
</f:view>

You get the picture.. the entire page is essentially just a set of nested components.. (In this case, I used imaginary custom "foo" layout components..)

The other markup centric approach has a lot more markup (Usually HTML) and only a minimal usage of components when needed:

<html>
<f:view>
<body>
<h2>My JSF App!!</h2>
<p>This app does neat stuff</p>
<h:form>
<table >
<tr><td><h:outputText></td><td><h:inputText></td></tr>
<tr><td><i>Some boilerplate text:</i></td><td><h:commandButton></td></tr>
</table>
</h:form>
</body>
</f:view>
</html>

As you can see, this page relies on markup (HTML) to set up the basic structure of the page and the JSF components are purely the dynamic portions.

For me, these code examples represent, two emerging philosophies with Faces development: a component centric vs. a markup centric approach.

In my view, those who have a more traditional Java development background, tend to like the first approach where the entire page is merely a collection of components. In this case, there really isn't a Web design experience where a page author "designs" the page using HTML/CSS/images.. Instead the page author merely assembles the app from preconfigured components. The components themselves can already have their look and field preprogrammed into them.

On the other hand, I see people who have more of a generic Web development/design background who may have dabbled with PHP, Cold Fusion and ASP may find the all component approach a little bit restrictive, since they may not necessarily have the luxury of just designing on the fly..

In general I see pros and cons for both approaches depending on their context. For large apps development groups, having a set of rich components with similar levels of service ensures 100% consistency.. The look and feel can be consistently dealt with along with other application development aspects such as internationalization, security etc.

On the other hand for smaller shops, or folks who have their comfort zone in a largely HTML design environment, an HTML (or markup) centric approach may be more to their liking. This approach also works well for adhoc application design prototyping.

So here's my question to you..

Which approach do you find yourself doing with JSF? Do you tend to use more markup than components, or do you prefer a much more component centric development experience?

Feel free to comment..

-Chris

( Oct 15 2005, 12:07:02 PM PDT ) Permalink Comments [11]

20051001 Saturday October 01, 2005

Building Dependent Select Menus in Faces

Many times in Web applications the value of one select menu (dropdown list) directly influences what should appear in a dependent list. For example a common example is to have either a country (or a state) dropdown menu and upon selection of the menu a dependent city menu appears. While Implementing dependent select menus can be done in various ways using JavaServer Faces, this How-To provides steps on how to build dependent list menus using Java HashMaps which are declared directly as managed beans.

Defining the HashMaps as managed beans

Faces provides the ability to declare Lists or Maps directly as managed beans in the faces-config.xml. Once defined in the faces-config.xml, Faces apps can easily access them using JSF EL or programmatically. For this example we will define the following Maps

CountriesMap - A Map of countries: France, United States, India.

This Map will drive a dependent set of Maps: UsCitiesMap, FrCitiesMap and InCitiesMap.

When the user selects one of the country names, the dependent list will automatically be loaded with the corresponding city Map values.

The HashMaps

CountriesMap

<managed-bean>
<managed-bean-name>CountriesMap</managed-bean-name>
<managed-bean-class>java.util.HashMap</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<map-entries>
<map-entry>
<key>France</key>
<value>fr</value>
</map-entry>
<map-entry>
<key>United States</key>
<value>us</value>
</map-entry>
<map-entry>
<key>India</key>
<value>in</value>
</map-entry>
</map-entries>
</managed-bean>

And the dependent city Maps..

UsCitiesMaps

<managed-bean>
<managed-bean-name>UsCitiesMap</managed-bean-name>
<managed-bean-class>java.util.HashMap</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<map-entries>
<map-entry>
<key>New York</key>
<value>ny</value>
</map-entry>
<map-entry>
<key>San Francisco</key>
<value>sf</value>
</map-entry>
<map-entry>
<key>Los Angeles</key>
<value>la</value>
</map-entry>
</map-entries>
</managed-bean>

FrCitiesMaps

<managed-bean>
<managed-bean-name>FrCitiesMap</managed-bean-name>
<managed-bean-class>java.util.HashMap</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<map-entries>
<map-entry>
<key>Paris</key>
<value>ps</value>
</map-entry>
<map-entry>
<key>Lyon</key>
<value>ly</value>
</map-entry>
<map-entry>
<key>Orlean</key>
<value>ol</value>
</map-entry>
</map-entries>
</managed-bean>

InCitiesMap

<managed-bean>
<managed-bean-name>InCitiesMap</managed-bean-name>
<managed-bean-class>java.util.HashMap</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<map-entries>
<map-entry>
<key>New Delhi</key>
<value>nd</value>
</map-entry>
<map-entry>
<key>Bangalore</key>
<value>bl</value>
</map-entry>
<map-entry>
<key>Calcutta</key>
<value>cc</value>
</map-entry>
</map-entries>
</managed-bean>

In order to display something before a country has been picked, an EmptyCities Map will also be defined.

EmptyCitiesMap

<managed-bean>
<managed-bean-name>EmptyCitiesMap</managed-bean-name>
<managed-bean-class>java.util.HashMap</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<map-entries>
<map-entry>
<key>empty</key>
<value>em</value>
</map-entry>
</map-entries>
</managed-bean>

Keep in mind that these Maps could of course be dynamically derived from a database or any datasource.

Here's the source code to our JSF JSP page which contains the two select menus.

<%@ page contentType="text/html;charset=windows-1252"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<f:view>
<html>
<head>
<title>deplist</title>
</head>
<body>
<h:form>
<p>
Country:<h:selectOneMenu onchange="submit()"
binding="#{Deplist_backing.inputCountry}" >
<f:selectItems value="#{CountriesMap}"/>
</h:selectOneMenu>
</p>
<p>
City:<h:selectOneMenu binding="#{Deplist_backing.inputCity}">
<f:selectItems value="#{Deplist_backing.cities}"/>
</h:selectOneMenu>
</p> </h:form> </body>
</html>
</f:view>

As you can see the page contains the two selectOneMenu components which have their child selectItems bound to #{CountriesMap} which is just the Map item from the faces-config.xml, and #{Deplist_backing.cities} which is a method which returns a Map object based on the value of the inputCountry component. The Deplist_backing object is managed bean which has the following source:

package backing;
import ../../page/java.util.Map.css;
import ../../page/javax.faces.component.html.HtmlSelectOneMenu.css;
import ../../page/javax.faces.context.FacesContext.css;
import ../../page/javax.faces.el.ValueBinding.css;
public class DepList {
  HtmlSelectOneMenu inputCountry, inputCity;
  // Method which returns the cities Map 
  // based on the value of inputCountry
  public Map getCities() {
    String cityMap = "";
    if (inputCountry.getValue() != null) {
      String countryKey = inputCountry.getValue().toString();
      if (countryKey.equals("fr"))
        cityMap = "FrCitiesMap";
      else if (countryKey.equals("us"))
        cityMap = "UsCitiesMap";
      else if (countryKey.equals("in"))
         cityMap = "InCitiesMap";
      else
         cityMap = "EmptyCitiesMap";
     }
     else {
       cityMap = "EmptyCitiesMap";
     }
   cityMap = "#{" + cityMap + "}";
   //retrieve correct cityMap and return
   FacesContext context = FacesContext.getCurrentInstance( );
   ValueBinding binding;
   binding = context.getApplication().createValueBinding(cityMap);
   return (Map) binding.getValue(context);   
  }
  public void setInputCountry(HtmlSelectOneMenu inputCountry) {
    this.inputCountry = inputCountry;
  }
  public HtmlSelectOneMenu getInputCountry() {
    return inputCountry;
  }
  public void setInputCity(HtmlSelectOneMenu inputCity) {
    this.inputCity = inputCity;
  }
  public HtmlSelectOneMenu getInputCity() {
    return inputCity;
  }
}

Notice how the method getCities first checks to see if a value exists for the inputCountry, if so that means the user has selected a country and the appropriate city Map must be returned. This is done by accessing the city Map from the managed beans facility and returning it.

And finally the registration of the class Deplist as managed bean Deplist_backing.

<managed-bean>
  <managed-bean-name>Deplist_backing</managed-bean-name>
  <managed-bean-class>backing.DepList</managed-bean-class>
  <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

And that's it.. when you run the JSP page, you will be able to select the country first and then select the city name.

( Oct 01 2005, 12:35:46 PM PDT ) Permalink Comments [1]

20050922 Thursday September 22, 2005

Ed's comments on JSF 1.2 other Faces stuff

Hey Ed! Nice blog post... :)

A very clear bit of info on JSF 1.2 and other fud type issues:

http://weblogs.java.net/blog/edburns/archive/2005/09/clearing_up_jsf_1.html

( Sep 22 2005, 05:55:25 PM PDT ) Permalink Comments [1]

20050920 Tuesday September 20, 2005

Building an EJB 3.0 Faces App - A HowTo

As promised.. here are the steps from my Openworld presentation demo

Building a database app with EJB 3.0 and ADF Faces with Oracle JDeveloper rel. 3 (10.1.3) Early Access 1

This how to describes how to build a simple database application which uses EJB 3.0 as its middle-tier and ADF Faces as its View. I used these exact steps in my intro to JDeveloper 10g presentation at OpenWorld 2005 in San Francisco. This application development process highlights the integrated support for EJB3.0, ADF Faces and the overall ADF framework.

Requirements...

  • JDeveloper 10.1.3 10g Release 3 (10.1.3) Early Access 1: Download and install Oracle JDeveloper 10g Release 3 (10.1.3) - Early Access 1 from otn.oracle.com. Note: the previous 10.1.3 beta release (build 223) does not have the features highlighted in this HowTo. To install, just unzip the zip file and run jdeveloper.exe (if on windows)
  • A database which is accessible from Oracle JDeveloper: Any Oracle database or JDBC compliant database will work as long as you have the JDBC drivers. This HowTo uses the Oracle common schema table hr.employees.

Steps...

  1. After starting JDeveloper make sure to establish a connection to your database by clicking on the "Connections" tab and then clicking on the "Database" node and selecting "Create New Database Connection".
  2. Create a database connection to either the common schema "hr" or any schema which has a table with data in it. (Note: The table will need to have a Primary Key defined.)
  3. Once your database connection has been successfully created, click on the "Applications Navigator".
  4. Create a new application by right-clicking on the "Application" node and selecting "New Application...".
  5. You can name the app "adfejbapp" and accept the defaults in the create application dialog. Note: Make sure to select "No Template" in the Applications Template: field.
  6. A "Create Project" will then automatically appear. Name the project "model" and click OK.

Building an EJB 3.0 Model

We'll now build an EJB 3.0 entity bean and session bean which allow for data operations on a database table.

  1. Right click the "model" project and select "New..." to invoke the New Gallery.
  2. Select the node Business-Tier->EJB to see the EJB wizard options. (Make sure Filter By: is "All Technologies")
  3. Select "CMP Entity Beans from Tables" and click OK.
  4. In step 1 of the wizard make sure to select the Enterprise JavaBeans 3.0 radio button and click "Next".
  5. In step 2 you should be able to select your connection that you created earlier (hr). Click Next.
  6. In step 3 click on the Auto-Query checkbox to query the current tables available. If using hr, double-click or shuttle over the "Employees" table. (Optional: You can edit the "Entity Name:" to be "Employee" instead of "Employees" since this object will represent a single employee record .) Click Next.
  7. In step 4 you can customize the package. I used: "com.persistence". Leave the other option as default. Click Next.
  8. In step 5 you can review all generation options and then click Finish. You now have an EJB3.0 entity bean which maps to your (employees) table. Save all and compile the project. Also feel free to inspect the actual Java code. You'll see the basic setter and getter methods in the Java class.
  9. Next you'll need to build a Session bean. This is the transient bean which your app will communicate with. Invoke the New Gallery as before (New...).
  10. This time select the "Session Bean" wizard in the same EJB gallery.
  11. In step 1, name the bean "EmpSession" and click Next.
  12. In step 2, customize the package and class name. I used "com.session.EmpSessionBean".
  13. In step 3, accept the default and click Next and Finish.
  14. Save all and compile. Also feel free to inspect your Session Bean. You'll see the different data operation methods like "findAllEmployee( )"...
  15. You have now finished your EJB 3.0 middle-tier.

Building a Faces View

Next we'll create a "view" project which will contain the JSF user interface for our EJB mid-tier.

  1. Create a new empty project using New...->General->Projects->Empty Project from the New Gallery.
  2. Name the project "view", click OK.
  3. Create a new JSF enabled JSP page using New...->Web Tier->JSF->JSF JSP.
  4. In step 1, select the default (J2EE 1.4).
  5. In step 2, name the page "emps.jsp" and click Next.
  6. In step 3, accept the default (no autobinding) and click Next.
  7. In steps 4-6 accept all the defaults and click Finish to generate an empty JSF JSP page.
  8. As the new page appears in the visual editor you'll see on the right side a "Component Palette" and "Data Controls" windows. For this exercise we'll use the Data Controls window, but we first have to populate it with the EJB session bean that was created in the model project.
  9. With the Data Controls window open, click open the model project and locate the EmpSessionBean.java file and drag and drop it into the Data Controls window. Click OK to accept the default EJB Interface chooser. You should now see the EmpSessionBean in the Data Control window.
  10. Save all.. Feel free to Build both projects again to make sure everything is fine.
  11. We'll now create a Read Only (data) table in the emps.jsp page. This is easily done by dragging and dropping from the Data Control window.
  12. In the Data Control window locate the method: "findAllEmployee" (or findAll**** depending on the name of your table). Open the findAll.. method to locate it's child node "Employee".
  13. Drag and drop the "Employee" child node of findAllEmployee( ) onto the emps.jsp.
  14. As you drop the item, you'll see a menu. Select "Create->Table->ADF Read Only Table".
  15. Click OK on the Client Project Libraries dialog.
  16. JDeveloper will then generate a read only data table which extracts its data from the findAllEmployee( ) method. You should now see the new table in the JSP visual editor.
  17. Save all, compile all.
  18. Optional: At this point you can test your application immediately by right-clicking and selecting Run on the emps.jsp page. You will see the read only table with navigation and column sorting available for free. (One of the benefits of ADF Faces)

Creating an Edit Form

This next set of steps show how to create an edit form and link it to the read only table

  1. For this next step, we'll create a new JSF page (edit.jsp) and navigation rules in the JSF Page Flow diagrammer. To invoke the Page Flow diagrammer, right click the "view" project and select "Open JSF Navigation". This will open the faces-config.xml in the JSF Page Flow diagrammer. We can now design the rest of the app from here.
  2. Add the existing emps.jsp into the page flow by dragging and dropping it from the file navigator on the left and dropping it onto the page flow diagram. You should then see it in the diagram
  3. Next, we'll add a new JSF page to the diagram by dragging and dropping a "JSF Page" from the palette on the right, onto the page flow diagram. Change the name of the new page to edit.jsp. Notice the new page has a yellow caution sign on it. This simply means that the page exists only in the drawing and hasn't been created yet.
  4. To generate the edit.jsp page, double-click it in the diagram. In the JSP wizard, you can immediately click Finish to generate the new edit.jsp page.
  5. Next we'll drop an Input Form in a similar fashion from before from the Data Control window.
  6. In the Data Control window in the same "findAllEmployee( )" node, drag the Employee node as before onto the new edit page.
  7. This time select, "Create->Forms->ADF Input Form". This will generate an input form using the ADF Faces JSF components.
  8. Save the edit.jsp page.
  9. Click back to the page flow diagram. We'll now create JSF navigation rules between the two pages.
  10. To create an "edit" nav rule from the emps.jsp page to the edit.jsp page, click on the "JSF Navigation Page" on the palette.
  11. Then click on the emps.jsp. You will see a connected line from the emps.jsp page.
  12. Mouse over to the edit.jsp page and click on it. You should now see a line connecting from the emps.jsp page to the edit.jsp.
  13. Change the "From Outcome" of the navigation case from "success" to "edit". This can be done in the Property Inspector or directly on the page flow navigation line.
  14. Next we'll create a "back"' navigation from the edit.jsp back to the emps.jsp page. In a similar fashion as before, create a navigation case from the edit.jsp page to the emps.jsp.
  15. This time change the "From Outcome" to "back".
  16. Save all. (Optional: you can check out the actual source of the faces-config.xml by clicking on the source tab at the bottom of the page flow diagram.
  17. Next we'll add buttons which use the JSF navigation cases to navigate between the two pages.
  18. Tab back to the emps.jsp page to edit it again. This time we'll use the Component Palette on the right instead of the Data Control window to drop a button onto the page.
  19. Select the Component Palette tab and select the palette page: "ADF Faces Core".
  20. Drag and drop the component "commandButton" onto the page. Place it directly under the table.
  21. In the Property Inspector, change the properties:
    text: Edit
    action: edit

    The text property is what is shown on the button and the action property allows the button to use the "edit" navigation case that we defined earlier.
  22. Now edit the page edit.jsp again.
  23. Drag and drop the same commandButton onto the page and place it under the form.
  24. In the Property Inspector, change the properties:
    text: Back
    action: back
  25. That's it! Save all..
  26. You can now run the application again. This time you can simply select the emps.jsp in the page flow, right-click and select Run.

You'll be able to browse and edit employee data with your pages!

For more fun, feel free to experiment with changing the look and feel of you app. See my previous blog posting on ADF Faces skins..

 

( Sep 20 2005, 11:19:03 AM PDT ) Permalink Comments [1]

20050919 Monday September 19, 2005

My Oracle Openworld Day 1

I just finished off Day 1 of Oracle's Openworld and so far so good...

Meet the Experts Session for JSF - rescheduled to Wednesday...

My first thing on the agenda today was to show up at the OTN Lounge for a "Meet the Experts" Session along with Jonas Jacobi and Adam Winer. Unfortunately there wasn't really much of a turn out because our names got added a bit late and didn't make it into the main program.. So..

Important: We'll be doing a follow up session at the OTN Lounge in Moscone West on Wednesday at 11am just after Debu's EJB 3.0 session..

Feel free to stop by and ask us any question about JSF and Oracle's JSF product offerings and strategy!

s586 - Introduction to Oracle JDeveloper 10g

At 1:30pm I gave a general introductory presentation on the latest JDeveloper 10g (10.1.3) release 3 where I showed the following:

  • Database, SQL, PL/SQL support
  • Java coding features, including refactoring and other advanced code editing features.
  • TopLink integration
  • New EJB 3.0 support
  • JavaServer Faces/ADF Faces support
  • Drag and Drop databinding with EJB3.0 and ADF
  • JDev's BPEL designer

All in all a lot of fun!! I was very happy to see that our EA build (3412) is holding up nicely and makes using EJB 3.0 and JSF very easy!

I'll post the exact steps of my EJB3.0/Faces demo today or tomorrow..

:)

( Sep 19 2005, 05:45:34 PM PDT ) Permalink Comments [2]

20050906 Tuesday September 06, 2005

Presentation on JSF and Oracle Available for Download

As I recently went to Santiago Chile and Buenos Aires Argentina, I presented on JavaServer Faces technology in general as well as Oracle's overall strategy on JSF. I also demonstrated Oracle's current and upcoming JSF support.

This presentation is now downloadable in PDF format at: http://www.orablogs.com/cschalk/presentations/cschalk-jsfprez-pdf.zip

Enjoy...

-Chris

( Sep 06 2005, 06:58:46 PM PDT ) Permalink Comments [2]

20050831 Wednesday August 31, 2005

Getting Familiar with the JSF Lifecycle with a PhaseListener

Those who are new to JSF may often hear about the "JSF Request Processing Lifecycle" but may not have a firm grasp of exactly what this lifecycle does..

Here is a small bit of code called a PhaseListener, which can be used to learn exactly how JSF's Request Processing Lifecycle works..

Here is a simple PhaseListener which executes at the beginning and end of each lifecycle phase.

package com.jsf;
import ../../page/javax.faces.event.PhaseListener.css;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
public class MyPhaseListener  implements PhaseListener
{
  public MyPhaseListener()
  {
  }
  public void beforePhase(PhaseEvent pe)
  {
   if (pe.getPhaseId() == PhaseId.RESTORE_VIEW)
      System.out.println("Processing new  Request!");
   System.out.println("before - " + pe.getPhaseId().toString());
  }
  public void afterPhase(PhaseEvent pe)
  { 
  System.out.println("after - " + pe.getPhaseId().toString());
  if (pe.getPhaseId() == PhaseId.RENDER_RESPONSE)
     System.out.println("Done with Request!\n");
  }
  public PhaseId getPhaseId()
  {  
    return PhaseId.ANY_PHASE;
  }
}

This announces (to your console) when each phase is starting and ending.. But before you can see it working though, you'll need to register it in the faces-config.xml

<lifecycle>
<phase-listener>com.jsf.MyPhaseListener />
</lifecycle>

Once you've registered your PhaseListener, you can start building a simple app which has a few input fields (UIInput) and perhaps a button (UICommand) on the page and when executed, it can also print out a message to the console..

For example you can then add a button onto a page:

<h:commandButton value="button" action="#{backingbean.button_action}"/<

With it bound to the action method in a managed bean:

public String button_action()
  {
    System.out.println("Action event processed...");
    return "success";
  }

When you run the page, you will see the following in your console:

05/08/31 20:32:46 Processing new  Request!
05/08/31 20:32:46 before - RESTORE_VIEW 1
05/08/31 20:32:46 after - RESTORE_VIEW 1
05/08/31 20:32:46 before - RENDER_RESPONSE 6
05/08/31 20:32:46 after - RENDER_RESPONSE 6
05/08/31 20:32:46 Done with Request!
05/08/31 20:32:57 Processing new  Request!
05/08/31 20:32:57 before - RESTORE_VIEW 1
05/08/31 20:32:57 after - RESTORE_VIEW 1
05/08/31 20:32:57 before - APPLY_REQUEST_VALUES 2
05/08/31 20:32:57 after - APPLY_REQUEST_VALUES 2
05/08/31 20:32:57 before - PROCESS_VALIDATIONS 3
05/08/31 20:32:57 after - PROCESS_VALIDATIONS 3
05/08/31 20:32:57 before - UPDATE_MODEL_VALUES 4
05/08/31 20:32:57 after - UPDATE_MODEL_VALUES 4
05/08/31 20:32:57 before - INVOKE_APPLICATION 5
05/08/31 20:32:57 Action event processed...
05/08/31 20:32:57 after - INVOKE_APPLICATION 5
05/08/31 20:32:57 before - RENDER_RESPONSE 6
05/08/31 20:32:57 after - RENDER_RESPONSE 6
05/08/31 20:32:57 Done with Request!

Notice on the first (non-postback) request it simply passes through two phases, RESTORE_VIEW and RENDER_RESPONSE.. This means it just creates the UI component tree, and then just renders it to the client.. You can then see the page in the browser. Next, you can click on the button and notice the messages in the console.. This time it will pass through the entire lifecycle. Notice that the button click action event is processed in the INVOKE_APPLICATION phase..

Now as an experiment, change the immediate attribute of the commandButton to true and watch how this affects when the action method is process.

Next, you may want to add an input field, and then add a ValueChangeListener which displays when a value has change..

A new input field...

<h:inputText value="foo">
 <f:valueChangeListener type="../../page/com.js"/>
</h:inputText>

And here is the code for the ValueChangeListener..

package com.jsf;
import ../../page/javax.faces.event.ValueChangeListener.css;
import ../../page/javax.faces.event.ValueChangeEvent.css;
import ../../page/javax.faces.event.AbortProcessingException.css;
public class MyValueChangeListener implements ValueChangeListener
{
  public MyValueChangeListener()
  {
  }
  public void processValueChange(ValueChangeEvent vce) throws AbortProcessingException
  {
     System.out.println("A value has changed!");
  }
}

In this fashion, you don't need to register this ValueChangeListener in the faces-config.xml.. You can just run your page and watch what happens in the console..

05/08/31 20:41:33 Processing new  Request!
05/08/31 20:41:33 before - RESTORE_VIEW 1
05/08/31 20:41:33 after - RESTORE_VIEW 1
05/08/31 20:41:33 before - RENDER_RESPONSE 6
05/08/31 20:41:33 after - RENDER_RESPONSE 6
05/08/31 20:41:33 Done with Request!

Now enter a new value in the input field and watch what happens..

5/08/31 20:42:42 Processing new  Request!
05/08/31 20:42:42 before - RESTORE_VIEW 1
05/08/31 20:42:42 after - RESTORE_VIEW 1
05/08/31 20:42:42 before - APPLY_REQUEST_VALUES 2
05/08/31 20:42:42 after - APPLY_REQUEST_VALUES 2
05/08/31 20:42:42 before - PROCESS_VALIDATIONS 3
05/08/31 20:42:42 A value has changed!
05/08/31 20:42:42 after - PROCESS_VALIDATIONS 3
05/08/31 20:42:42 before - UPDATE_MODEL_VALUES 4
05/08/31 20:42:42 after - UPDATE_MODEL_VALUES 4
05/08/31 20:42:42 before - INVOKE_APPLICATION 5
05/08/31 20:42:42 Action event processed!
05/08/31 20:42:42 after - INVOKE_APPLICATION 5
05/08/31 20:42:42 before - RENDER_RESPONSE 6
05/08/31 20:42:42 after - RENDER_RESPONSE 6
05/08/31 20:42:42 Done with Request!

As you play with adding input fields, and later validations etc. you'll be able to see exactly where each portion of code is being executed!

Have fun!

-Chris

( Aug 31 2005, 10:31:03 PM PDT ) Permalink Comments [7]

Presentations in Chile and Argentina

Sorry for not posting in a few days.. As always, work has kept me quite busy.

Having just presented at an Oracle Developer Day in Dallas, I was asked if I could go to Santiago Chile and Buenos Aires Argentina to do a number of presentations and customer/partner meetings.. in spanish!

So far so good. I had a great time doing a half day workshop on JSF technology. The folks at the Oracle Chile office were extremely nice and appreciated my short notice availability. I wish had more time though to actually see the city.. :( I could have also gone skiing. The snow covered mountains on the outskirts of the city look awesome!

Presenting on the merits of JSF to audiences who are still fairly new to this technology is a piece of cake.

They are generally surprised at how easy it is to build simple apps and are also extremely impressed by the value-add Faces component libraries - especially ADF Faces.

For example I've been building an app, and then was able to access the same app using different clients such as a telnet client, a Palm simulator client and a GAIM IM client.. Fun stuff!

( Aug 31 2005, 07:32:04 PM PDT ) Permalink Comments [2]

20050816 Tuesday August 16, 2005

New Article on Building Custom JSF Components

Hello,

The ServerSide.com just posted a new article of mine which shows how to build custom JSF UI components.

I wrote this article with an intention to introduce developers to JSF component development by starting with the classic HelloWorld example and then by customizing it later and turning it into a Stock report component which calls a Web Service.

Feel free to check it out at:

http://www.theserverside.com/articles/article.tss?l=BuildingCustomJSF

-Chris

( Aug 16 2005, 12:50:04 PM PDT ) Permalink Comments [4]


Archives
Links
Referrers
Recent Posts