Section 9.2. Writing a Custom JSF Component


9.2. Writing a Custom JSF Component

Using JavaServer Faces Technology with AJAX, by Greg Murray et al. (https://bpcatalog.dev.java.net/nonav/ajax/jsf-ajax/index.html) describes the three ways to use Ajax with a JavaServer Faces component:

  • Use a listener to service the backend request.

  • Use a servlet in your JSF application to service the Ajax request.

  • Use a servlet outside of JSF to service the backend request.

In earlier chapters, we used servlets to service the backend requests. This time, we'll use a listener; our custom JSF component will be entirely encapsulated in the JSF lifecycle. To keep things simple, we'll stick with the same example used in the previous chapters: we'll use Ajax to populate city and state fields in an HTML form based on a user-entered zip code. Figure 9-2 shows where we're headed.

Figure 9-2. Zip code lookup with JSF and Ajax


We could simply add a custom JSP tag to a JSF view and write a servlet to service the Ajax request. This is a quick way to inject Ajax into a JSF application; it's not fundamentally different from the techniques we've already covered. But if you want to use the JSF framework, you need to write a custom component.

9.2.1. Writing the JSP Page for the JSF Application

The JSP page for this application (Example 9-1) uses JSF's core and HTML tag libraries. In addition to these libraries, we'll develop a new Ajax tag library in this chapter. Our library will contain only one tag: zipCode.

Example 9-1. The view for the JSF application: index.jsp

 <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@ taglib uri="http://ajax.oreilly.com/jsf/ajax" prefix="ajax" %> <html> <f:view>     <head>         <title>JSF Page</title>     </head>     <body>         <h:form>             <h3>JavaServer Faces: State and City Lookup with Ajax</h3>             <ajax:zipCode zipcode state city                           url="zipcodes" />         </h:form>     </body> </f:view> </html> 

The web application can't access this JSP directly by including a <welcome> element in the web.xml file. The JSF application must render this page through the JSF lifecycle, and that cannot happen if the web container accesses the page directly. Instead, the web application must access a JSP page that forwards to the JSF application. That JSP is forward.jsp. Here's how it's configured in web.xml:

 <web-app> ...     <welcome-file-list>         <welcome-file>forward.jsp</welcome-file>     </welcome-file-list> ... </web-app> 

forward.jsp (Example 9-2) uses a <jsp:forward> tag to index.faces to render index.jsp from the JSF application lifecycle.

Example 9-2. forward.jsp

 <%@ page language="java" pageEncoding="UTF-8" %> <jsp:forward page="/index.faces" /> <html>     this page should forward to the application </html> 

It may seem odd that the page forwards to index.faces rather than to index.jsp itself, but that's how it works. The JSF application references each page with a .faces extension; the JavaServer Faces servlet, javax.faces.webapp.FacesServlet, strips off the .faces extension and loads the JSP file with the .jsp extension.

9.2.2. Configuring JSF: web.xml and faces-config.xml

The configuration resource file is unique to JavaServer Faces. As you can see in Example 9-3, web.xml defines the javax.faces.CONFIG_FILES parameter to point to faces-config.xml. web.xml also configures the FacesServlet that runs the JSF environment, setting it to intercept any URL with a .faces extension.

Example 9-3. web.xml

 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee"          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4"          xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee          http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">     <context-param>         <param-name>javax.faces.CONFIG_FILES</param-name>         <param-value>/WEB-INF/faces-config.xml</param-value>     </context-param>     <servlet>         <servlet-name>Faces Servlet</servlet-name>         <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>         <load-on-startup>0</load-on-startup>     </servlet>     <servlet-mapping>         <servlet-name>Faces Servlet</servlet-name>         <url-pattern>*.faces</url-pattern>     </servlet-mapping>     <welcome-file-list>         <welcome-file>forward.jsp</welcome-file>     </welcome-file-list> </web-app> 

The faces-config.xml file controls much of the behavior of the JSF application. It configures the JSF lifecycle, any beans that will be used in the lifecycle, the renderers that will be used, and so on. Here is a list of elements that can be used in faces-config.xml:


<application>

Declares the pluggable classes for the JSF application.


<component>

Declares the class for a component type.


<converter>

Declares the class that implements the converter.


<description>

Contains the element description, which is used in some development tools.


<display-name>

Contains the display name, which is used by some development tools.


<factory>

Declares replacements for the factory classes.


<lifecycle>

Lists the lifecycle phase listeners.


<managed-bean>

Declares a managed bean; a managed bean is instantiated and initialized automatically by the JSF framework.


<navigation-rule>

Creates a rule for the navigation handler.


<render-kit>

Declares a render kit or custom renderers for the default render kit.


<validator>

Declares the class for a validator.

Our faces-config.xml file is shown in Example 9-4. This simple application uses only the <render-kit>, <component>, and <lifecycle> elements.

Example 9-4. faces-config.xml

 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces     Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd"> <faces-config>     <lifecycle>         <phase-listener>com.oreilly.ajax.ZipCodePhaseListener</phase-listener>     </lifecycle>     <render-kit>         <description>             Render kit implementation for the Ajax JSF components         </description>         <renderer>             <component-family>javax.faces.Input</component-family>             <renderer-type>ZipCode</renderer-type>             <renderer-class>com.oreilly.ajax.ZipCodeRenderer</renderer-class>         </renderer>     </render-kit>     <component>         <display-name>O'Reilly Zip Code</display-name>         <component-type>oreilly.ajax.ZipCode</component-type>         <component-class>com.oreilly.ajax.ZipCode</component-class>     </component> </faces-config> 

The <lifecycle> element contains a <phase-listener> element, which defines a class that can be called at the end of each phase (in this case, ZipCodePhaseListener).

The <render-kit> element in this configuration contains one <renderer> element, which is set to com.oreilly.ajax.ZipCodeRenderer. Render kits can contain one or more renderers. The default render kit contains renderers for HTML, but render kits can be developed for other markup languages. A renderer draws a specific component. For example, a form renderer in the HTML render kit renders the <form> element (more specifically, the renderer's encodeBegin( ) method renders the <form> tag, and the encodeEnd( ) method renders the closing </form> tag). The faces-config.xml file in Example 9-4 defines a renderer that uses the com.oreilly.ajax.ZipCodeRenderer class to build the HTML display and Ajax code that our JSF tag needs.

The <component> element defines the JSF component that is used in the application. In this case, the com.oreilly.ajax.ZipCode class is a custom component; it is used to get the application's HTML input.

Figure 9-3 models the configuration of our application. Bear in mind that this is a very basic example; a real-world application will almost certainly have a more complex configuration containing many other elements.

Figure 9-3. JavaServer Faces configuration





Ajax on Java
Ajax on Java
ISBN: 0596101872
EAN: 2147483647
Year: 2007
Pages: 78

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net