Development Environments for JSF

Sample Application Analysis

Web applications have two parts: the presentation layer and the business logic. The presentation layer is concerned with the look of the application. In the context of a browser-based application, the look is determined by the HTML tags that specify layout, fonts, images, and so on. The business logic is implemented in the Java code that determines the behavior of the application.

Some web technologies intermingle HTML and code. That approach is seductive since it is easy to produce simple applications in a single file. But for serious applications, mixing markup and code poses considerable problems.

Professional web designers know about graphic design, but they typically rely on tools that translate their vision into HTML. They would certainly not want to deal with embedded code. On the other hand, programmers are notoriously unqualified when it comes to graphic design. (The example programs in this book bear ample evidence.)

Thus, for designing professional web applications, it is important to separate the presentation from the business logic. This allows both web designers and programmers to focus on their core competences.

In the context of JSF, the application code is contained in beans, and the design is contained in web pages. We look at beans first.

Beans

A Java bean is a class that exposes properties and events to an environment such as JSF. A property is a named value of a given type that can be read and/or written. The simplest way to define a property is to use a standard naming convention for the reader and writer methods, namely, the familiar get/set convention. The first letter of the property name is changed to upper case in the method names.

For example, the UserBean class has two properties, name and password, both of type String:

  public class UserBean {      public String getName() { . . . }      public void setName(String newValue) {. . . }      public String getPassword() { . . . }      public void setPassword(String newValue) { . . . }      . . .   }

The get/set methods can carry out arbitrary actions. In many cases, they simply get or set an instance field. But they might also access a database or a JNDI (Java Naming and Directory Interface) directory.

Note

According to the bean specification, it is legal to omit a read or write method. For example, if getPassword is omitted, then password is a write-only property. That might indeed be desirable for security reasons. However, JSF deals poorly with this situation and throws an exception instead of taking a default action when a read or write method is absent. Therefore, it is best to give read/write access to all bean properties.


In JSF applications, you use beans for all data that needs to be accessible from a page. The beans are the conduits between the user interface and the backend of the application.

JSF Pages

You need a JSF page for each browser screen. Depending on your development environment, JSF pages typically have the extension .jsp or .jsf. At the time of this writing, the extension .jsp requires less configuration effort. For that reason, we use the .jsp extension in the examples of this book.

Note

The extension of the page files is .jsp or .jsf, whereas in the preferred configuration, the extension of the page URLs is .faces. For example, when the browser requests the URL http://localhost:8080/login/index.faces, the URL extension .faces is mapped to the file extension.jsp and the servlet container loads the file index.jsp. This process sounds rather byzantine, but it is a consequence of implementing JSF on top of the servlet technology.


Now we take another look at the first page of our sample application in Listing 1-1.

The page starts out with the tag library declarations:

  <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>   <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>

The JSF implementation defines two sets of tags. The HTML tags generate HTML-specific markup. If you want your web application to render pages for an alternative client technology, you must use a different tag library. The core tags are independent of the rendering technology. For example, you need the f:view tag both for HTML pages and for pages that are rendered by a cell phone.

Note

You can choose any prefixes for tags, such as faces:view and html:inputText. In this book, we use f for the core tags and h for the HTML tags.


Much of the page is similar to an HTML form. Note the following differences:

  • All JSF tags are contained in an f:view tag.

  • Instead of using an HTML form tag, you enclose all the JSF components in an h:form tag.

  • Instead of using the familiar input HTML tags, use h:inputText, h:inputSecret, and h:commandButton.

We discuss all standard JSF tags and their attributes in Chapters 4 and 5. In the first three chapters, we can get by with input fields and command buttons.

The input field values are bound to properties of the bean with name user:

  <h:inputText value="#{user.name}"/>

You will see the declaration of the user variable in "Navigation" on page 16. The #{...} delimiters are explained in "The Syntax of Value Expressions" on page 64 of Chapter 2.

When the page is displayed, the framework calls the getName method to obtain the current property value. When the page is submitted, the framework invokes the setName method to set the value that the user entered.

The h:commandButton tag has an action attribute whose value is used when specifying navigation rules:

  <h:commandButton value="Login" action="login"/>

We discuss navigation rules in "Navigation" on page 16. The value attribute is the string that is displayed on the button.

The second JSF page of our application is even simpler than the first. It uses the h:outputText tag to display the username (see Listing 1-3).

Listing 1-3. login/web/welcome.jsp

  1. <html>   2.    <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>   3.    <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>   4.   5.    <f:view>   6.       <head>   7.          <title>A Simple JavaServer Faces Application</title>   8.       </head>   9.       <body>  10.          <h:form>  11.             <h3>  12.                Welcome to JavaServer Faces,  13.                <h:outputText value="#{user.name}"/>!  14.             </h3>  15.          </h:form>  16.       </body>  17.    </f:view>  18. </html>

Note

We use a plain and old-fashioned format for our JSF pages so that they are as easy to read as possible.

XML-savvy readers will want to do a better job. First, it is desirable to use proper XML for the tag library declarations, eliminating the <%...%> tags. Moreover, you will want to emit a proper DOCTYPE declaration for the generated HTML document.

The following format solves both issues:

<?xml version="1.0" ?> <jsp:root version="2.0"       xmlns:jsp="http://java.sun.com/JSP/Page"       xmlns:f="http://java.sun.com/jsf/core"       xmlns:h="http://java.sun.com/jsf/html">    <jsp:directive.page contentType="text/html"/>    <jsp:output omit-xml-declaration="no"          doctype-root-element="html"          doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"          doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>     <f:view>       <html xmlns="http://www.w3.org/1999/xhtml">          <head>             <title>A Simple Java Server Faces Application</title>          </head>          <body>             <h:form>             . . .             </h:form>          </body>       </html>    </f:view> </jsp:root>     

If you use an XML-aware editor, you should seriously consider this form.


Caution

You sometimes see naive page authors produce documents that start with an HTML DOCTYPE declaration, like this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html>    <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>    <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>    <f:view>    . . .

This may have been acceptable at one time, but nowadays, it is quite reprehensible. Plainly, this document is not an "HTML 4.01 Transitional" document. It merely aims to produce such a document. Many XML editors and tools do not take it kindly when you lie about the document type. Therefore, either omit the DOCTYPE altogether or follow the outline given in the preceding note.


Navigation

To complete our JSF application, we need to specify the navigation rules. A navigation rule tells the JSF implementation which page to send back to the browser after a form has been submitted.

In this case, navigation is simple. When the user clicks the login button, we want to navigate from the index.jsp page to welcome.jsp. You specify this navigation rule in the faces-config.xml file:

  <navigation-rule>      <from-view-id>/index.jsp</from-view-id>      <navigation-case>         <from-outcome>login</from-outcome>         <to-view-id>/welcome.jsp</to-view-id>      </navigation-case>   </navigation-rule>

The from-outcome value matches the action attribute of the command button of the index.jsp page:

  <h:commandButton value="Login" action="login"/>

In addition to the navigation rules, the faces-config.xml file contains the bean definitions. Here is the definition of the user bean:

   <managed-bean>       <managed-bean-name>user</managed-bean-name>       <managed-bean-class>          com.corejsf.UserBean       </managed-bean-class>       <managed-bean-scope>session</managed-bean-scope>    </managed-bean>

You can use the bean name, user, in the attributes of the user interface components. For example, index.jsp contains the tag

  <h:inputText value="#{user.name}"/>

The value attribute refers to the name property of the user bean.

The managed-bean-class tag specifies the bean class, in our case, com.corejsf.UserBean. Finally, the scope is set to session. This means that the bean object is available for one user across multiple pages. Different users who use the web application are given different instances of the bean object.

Listing 1-4 shows the complete faces-config.xml file.

Note

JSF 1.2 uses a schema declaration to define the syntax of a configuration file. The configuration tags are enclosed in

<faces-config xmlns="http://java.sun.com/xml/ns/javaee"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee         http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"    version="1.2">    . . . </faces-config> JSF 1.1 uses a DOCTYPE declaration instead: <!DOCTYPE faces-config PUBLIC    "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"    "http://java.sun.com/dtd/web-facesconfig_1_0.dtd"> <faces-config>    . . . </faces-config>

We recommend that you use an XML editor that understands XML Schema declarations. If you use Eclipse, a good choice is the XMLBuddy plugin (http://xmlbuddy.com).


Listing 1-4. login/web/WEB-INF/faces-config.xml

  1. <?xml version="1.0"?>   2. <faces-config xmlns="http://java.sun.com/xml/ns/javaee"   3.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   4.    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   5.         http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"   6.    version="1.2">   7.    <navigation-rule>   8.       <from-view-id>/index.jsp</from-view-id>   9.       <navigation-case>  10.          <from-outcome>login</from-outcome>  11.          <to-view-id>/welcome.jsp</to-view-id>  12.       </navigation-case>  13.    </navigation-rule>  14.  15.    <managed-bean>  16.       <managed-bean-name>user</managed-bean-name>  17.       <managed-bean-class>com.corejsf.UserBean</managed-bean-class>  18.       <managed-bean-scope>session</managed-bean-scope>  19.    </managed-bean>  20. </faces-config>

Servlet Configuration

When you deploy a JSF application inside an application server, you need to supply a configuration file named web.xml. Fortunately, you can use the same web.xml file for most JSF applications. Listing 1-5 shows the file.

Listing 1-5. login/web/WEB-INF/web.xml

  1. <?xml version="1.0"?>   2. <web-app xmlns="http://java.sun.com/xml/ns/javaee"   3.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   4.    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   5.       http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"   6.    version="2.5">   7.    <servlet>   8.       <servlet-name>Faces Servlet</servlet-name>   9.       <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>  10.       <load-on-startup>1</load-on-startup>  11.    </servlet>  12.  13.    <servlet-mapping>  14.       <servlet-name>Faces Servlet</servlet-name>  15.       <url-pattern>*.faces</url-pattern>  16.    </servlet-mapping>  17.  18.    <welcome-file-list>  19.       <welcome-file>index.html</welcome-file>  20.    </welcome-file-list>  21. </web-app>

The only remarkable aspect of this file is the servlet mapping. All JSF pages are processed by a special servlet that is a part of the JSF implementation code. To ensure that the correct servlet is activated when a JSF page is requested, the JSF URLs have a special format. In our configuration, they have an extension .faces.

For example, you cannot simply point your browser to http://localhost:8080/login/index.jsp. The URL has to be http://localhost:8080/login/index.faces. The servlet container uses the servlet mapping rule to activate the JSF servlet, which strips off the faces suffix and loads the index.jsp page.

Note

You can also define a prefix mapping instead of the .faces extension mapping. Use the following directive in your web.xml file:

<servlet-mapping>    <servlet-name>Faces Servlet</servlet-name>    <url-pattern>/faces/*</url-pattern> </servlet-mapping>

Then use the URL http://localhost:8080/login/faces/index.jsp. That URL activates the JSF servlet, which then strips off the faces prefix and loads the file /login/index.jsp.


Note

If you want to use a .jsf extension for JSF page files, then you need to configure your web application so that it invokes the JSP servlet for files with that extension. Use the following mapping in the web.xml file:

<servlet-mapping>    <servlet-name>jsp</servlet-name>    <url-pattern>*.jsf</url-pattern> </servlet-mapping>

You now need to tell the JSF implementation to map the .faces extension of the URLs to the .jsf extension of the associated files.

<context-param>    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>    <param-value>.jsf</param-value> </context-param>

Note that this configuration affects only the web developers, not the users of your web application. The URLs still have a .faces extension or /faces prefix.


Note

If you use an older application server that supports version 2.3 of the servlet specification, you use a DTD (DOCTYPE declaration) instead of a schema declaration in the web.xml file. The DTD is as follows:

<!DOCTYPE web-app PUBLIC    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"    "http://java.sun.com/dtd/web-app_2_3.dtd">


The Welcome File

When a user enters a directory URL such as http://localhost:8080/login, the application server automatically loads the index.jsp page when it is present. Unfortunately, that mechanism does not work smoothly with JSF pages because the JSF processing phase is skipped.

To overcome this issue, you can supply an index.html file that automatically redirects the user to the proper faces URL. Listing 1-6 shows such an index file.

Listing 1-6. login/web/index.html

  1. <html>   2.    <head>   3.       <meta http-equiv="Refresh" content= "0; URL=index.faces"/>   4.       <title>Start Web Application</title>   5.    </head>   6.    <body>   7.       <p>Please wait for the web application to start.</p>   8.    </body>   9. </html>

Finally, it is a good idea to specify index.html as the welcome file in web.xml. See the welcome-file tag in Listing 1-5 on page 18.

Note

The index.html file redirects the browser to the index.faces URL. It is slightly more efficient to use a JSP forward action instead. Create a page, say, start.jsp, that contains the line

<jsp:forward page="/index.faces"/>

Then set this page as the welcome-file in the web.xml configuration file.



Core JavaServerT Faces
Core JavaServer(TM) Faces (2nd Edition)
ISBN: 0131738860
EAN: 2147483647
Year: 2004
Pages: 84

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