`
joerong666
  • 浏览: 411126 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Getting started with JSF, Facelets, Eclipse WTP an

阅读更多
Added by Rick Hightower, last edited by Rick Hightower on Dec 21, 2006
<!---->

In this first tutorial we will build the classic JSF calculator application. In this tutorial you will download and install Eclipse Web Tools Project (WTP), Tomcat (a free application server), Facelets and the Faces console.

This app uses JSF, Facelets and Eclipse WTP (Web Tools Project). Facelets fits the JSF component model better than JSP. Eclipse WTP can provide code completion for Facelets if we trick it into thinking the Facelet is a JSP in XML file format.

The focus is on tools that are freely available (Eclipse, Sun's JSF RI, and Facelets).

Prereqs

The tutorial assumes knowledge of Java web development (JSP, Servlets) and general knowledge of using Eclipse. We do not assume knowledge of JSF, Facelets or WTP.

Here is the source code for this tutorial

tutorial1.zip

WARTAC Weapons Acquisition

This tutorial is as much about tools acquisition as it is JSF so get ready to start downloading.

  1. Download and install Eclipse WTP
  2. Download and install Tomcat
  3. Install the Faces console (pending)
  4. Get the JSF jar files from Sun
  5. Get the Facelets jar files from Java.net.
  6. Create a new web project in Eclipse WTP and setup JSF and Facelets

Download and install Eclipse WTP

For this tutorial we are going to use the freely available Eclipse WTP project.

"The Eclipse Web Tools Platform (WTP) project extends the Eclipse platform with tools for developing J2EE Web applications. The WTP project includes the following tools: source editors for HTML, Javascript, CSS, JSP, SQL, XML, DTD, XSD, and WSDL; graphical editors for XSD and WSDL; J2EE project natures, builders, and models and a J2EE navigator; a Web service wizard and explorer, and WS-I Test Tools; and database access and query tools and models."
from http://www.eclipse.org/webtools/

Go to http://www.eclipse.org/webtools/ and download the latest release of WTP. (This tutorial is using release 1.5.2).

Step by step:

  1. Go to http://www.eclipse.org/webtools/
  2. Click on the downloads link in the left navigation bar
  3. Select the latest stable build number from the list of releases.
  4. Select the wtp-all-in-one-sdk-*win32.zip file. (For windows. There is a release per OS. Choose accordingly).
  5. Pick a download site by clicking its associated link.
  6. Select the wtp-all-in-one-sdk-*win32.zip file.
  7. Get a cup of coffee... come back in 1/2 hour or so.
  8. To install Eclipse, just unzip it to c:\IDEs\WTP_152 (create dir first). This should create a directory called C:\IDEs\WTP_152\eclipse. Create a shortcut to C:\IDEs\WTP_152\eclipse\eclipse.exe and place it on your desktop.
  9. Run Eclipse and shut down the welcome screen.

Download and install Tomcat

Go to http://tomcat.apache.org/ and download the latest release of Tomcat. (This tutorial is using release 5.5.20).

Step by step:

  1. Go to http://tomcat.apache.org/
  2. Click on the Tomcat 5.x link from the Download navigation area on the left
  3. Select the Core zip under 5.5.20.
  4. Save the zip file
  5. Unzip the zip file to a directory on your disk (i.e., c:\tools) This should create a directory called C:\tools\apache-tomcat-5.5.20

Install the Faces Console

I am going to skip this part for now b/c....

Hey Rick,

I have added some fixes to JSF Console that allows it to edit 1.2 config files, but I have not made an official release with the changes. Perhaps I could do that so that you can include it in your article. Let me know what you think.

James Holmes

Get the JSF jar files from Sun

Now we need to get the JSF jar files from Sun. This tutorial uses JSF 1.2_03.

Step by Step:

  1. Go to https://javaserverfaces.dev.java.net/servlets/ProjectDocumentList?folderID=6481&expandFolder=6481&folderID=1504
  2. Click on the link jsf-1_2_03.zip
  3. Download zip file and expand it to C:\tools\jsf. This will create a directory called C:\tools\jsf\jsf-1.2_03-b09-FCS.
  4. Review the JSF documents at file:///C:/tools/jsf/jsf-1.2_03-b09-FCS/docs/index.html (on my machine file:///D:/tools/jsf/jsf-1.2_03-b09-FCS/docs/index.html since I have no room on my C: drive).

Get the Facelets jar files from Java.net.

Now we need to get the Facelets jar files from http://java.net. This tutorial uses Facelets instead of JSP because JSP does not work well with JSF. Facelets looks like JSP but is geared for JSF. A Facelet is a template that creates a JSF component tree. A JSP is a template that creates a Servlet. Facelets are the way to go with JSF. We use facelets-1.1.11 for this tutorial because it was the latest at the time.

Step by step:

  1. Go to https://facelets.dev.java.net/servlets/ProjectDocumentList?folderID=3635&expandFolder=3635&folderID=0
  2. Download facelets-1.1.11 by clicking on the facelets-1.1.11 link
  3. Download zip file and expand it to C:\tools\facelets. This will create a directory called C:\tools\facelets\facelets-1.1.11.
  4. Review the Facelets documents at file: file:///C:/tools/facelets/facelets-1.1.11/docs/dev/docbook.html (file:///D:/tools/facelets/facelets-1.1.11/docs/dev/docbook.html for me).

Create a new web project in Eclipse WTP and setup JSF and Facelets

Step by step:

  1. Start Eclipse WTP if it is not started
  2. Create a new Eclipse project
    1. Go to menu File->New->Project...
    2. From the New Project Dialog select Web->Dynamic Web Project from the Wizard Tree
    3. From the New Dynamic Web Project Dialog fill out the project info
      1. Set the Project Name to JSFSpringHibernateTut
      2. Leave all other fields to the default
      3. Hit the Next button
    4. From the Project Facets Dialog...
      1. See that the Dynamic Module and Java Module are selected
      2. Hit the Next button
    5. From the Web Module Dialog...
      1. Accept the Defaults
      2. Hit the Finish button
  3. Copy the JSF jar files to the WebContent/WEB-INF/lib folder
    1. Copy the JSF jar files from C:\tools\jsf\jsf-1.2_03-b09-FCS\lib to WebContent/WEB-INF/lib
    2. INFO: You can drag and drop files from the Windows File Explorer to Eclipse
    3. INFO: To see the jar files (jsf-api.jar, jsf-impl.jar) that were copied you may want to switch Eclipse to the Resource Perspective
  4. Copy the Facelets jar files to the WebContent/WEB_INF/lib folder
    1. Copy the Facelets jsf-faclets.jar from C:\tools\facelets\facelets-1.1.11 to WebContent/WEB-INF/lib
    2. Copy the Facelets Universal EL jar files (el-api.jar, el-ri.jar) from C:\tools\facelets\facelets-1.1.11\lib to WebContent/WEB-INF/lib
  5. NOTE: You should have the following jar files in your web project.
  6. Copy the tld file from jsf-ui.tld to WebContent/WEB-INF/. (Donated from Exadel to the Facelets project)
  7. INFO: For background info on Facelets please read Facelets fits JSF like a Glove
  8. Configure JSF and Facelets as follows in WebContent/WEB-INF/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">
    
    	<display-name>JSFSpringHibernateTut</display-name>
    	<description>JSF, Spring, Hibernate tutorial using Eclipse WTP.</description>
    
    	<!-- Use Documents saved as *.jspx for Facelets-->
    	<context-param>
    		<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    		<param-value>.jspx</param-value>
    	</context-param>
    
    
    	<!-- Faces Servlet -->
    	<servlet>
    		<servlet-name>Faces Servlet</servlet-name>
    		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    
    
    	<!-- Faces Servlet Mapping -->
    	<servlet-mapping>
    		<servlet-name>Faces Servlet</servlet-name>
    		<url-pattern>*.faces</url-pattern>
    	</servlet-mapping>
    
    	<welcome-file-list>
    		<welcome-file>index.jspx</welcome-file>
    	</welcome-file-list>
    
    </web-app>
  9. Configure Facelets into JSF by creating a WebContent/WEB-INF/faces-config.xml file as follows:
    WebContent/WEB-INF/faces-config.xml
    <?xml version='1.0' encoding='UTF-8'?>
    
    
    <!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>
    
    	<application>
    		<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
    	</application>
    
    </faces-config>

Install a new Tomcat Server in Eclipse WTP

Step by step:

  1. Ensure you are in J2EE Perspective (Navigate to menu Window->Open Perspective->J2EE if needed).
  2. Open up the Server View Pane, Right click in the Window
  3. Select Menu Item New->Server (see picture above)
  4. In the New Server dialog, select the tree node Apache->Tomcat v5.5 Server.
  5. Hit the Next button
  6. Fill out the Tomcat Server Dialog as follows:
  7. Hit the Next button
  8. Add the JSFSpringHibernateTut project to the Configured project list
  9. Hit the Finish button
Warning

If you see the following error when we deploy the app later:

java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: 
javax.faces.context.FacesContextFactory

This is because there is an issue with Tomcat. Jacob Hookum described this as follows on my blog:

"There are hotdeploy issues with tomcat and configure listeners, something that's being corrected in TC6
and backported to Tomcat 5.5." http://jroller.com/page/RickHigh?entry=trying_to_get_jsf_1

While we wait for this to make it into Tomcat, Cagatay Civici send the following solution:

It seems to be a listener issue. Listener is possibly configured in a tld inside jsf-impl.jar and Tomcat 5.5.20
can't extract that info. Configuring the listener inside web.xml should solve it. I remember an issue a
similar thing when using Tomcat 5.5.20 with myfaces. Previous versions of Tomcat works fine with this.

This equates to adding the following web.xml to workaround this problem:

<listener>
		<listener-class>
			com.sun.faces.config.ConfigureListener
		</listener-class>
	</listener>

	<!-- Listener implementation to handle web application lifecycle
		events -->
	<listener>
		<listener-class>
			com.sun.faces.application.WebappLifecycleListener
		</listener-class>
	</listener>

Create some pages

Next we want to create our first Facelet and run it.

  1. Create a new file in WebContent called index.jsp with the following contents:
    index.jsp
    <jsp:forward page="index.faces"/>
  2. Create a index.jspx Facelet as follows:
    1. Right click WebContent folder
    2. Select menu item New->JSP
    3. in the JavaServer Page dialog, type the File Name: index.jspx
    4. Hit the Next button
    5. From the templates select "New JSP File (xhtml, xml syntax)
    6. Change the index.jspx file as follows:
      index.jspx
      <?xml version="1.0" encoding="ISO-8859-1" ?>
      <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" 
      	xmlns:ui="http://java.sun.com/jsf/facelets"
      	xmlns:h="http://java.sun.com/jsf/html"
      	xmlns:f="http://java.sun.com/jsf/core"
      	version="2.0">
      
      <ui:composition>
      
      <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
      <title>Hello World</title>
      </head>
      <body>
      	<h:outputText value="Hello World!"/>
      </body>
      </html>
      </ui:composition>
      
      </jsp:root>

Notice we added the Facelets ui taglib and the JSF taglibs by adding the ui name space as follows:

Notice we can get code completion with Facelets because Eclipse WTP thinks this Facelet page is a JSP XML page. One of the biggest complaints about Facelets is the lack of code completion so this is a boon!

Running our first Facelet

(At this point, this works best with Mozilla, later it won't matter.)

  1. Right click the index.jsp and Run As->Run on Server

Congrats! You are done with this step. Get ready for the home stretch. Get a cup of coffee and come back to write the backing beans, navigation rules and the rest of this first app.

Calculator application

I wrote a Calcualtor application for IBM developerWorks in my infamous article JSF for nonbelievers: Clearing the FUD about JSF.

The example is a simple Calculator application. The goal in creating the application is to present a page to the end user that allows him or her to enter two numbers. Therefore the page has two text fields, two labels, two error-message locations, and a Submit button. The text fields are for entering the numbers. The labels are for labeling the text fields. The error message locations are to display validation or data-conversion error messages for the text fields. There are three JSP pages: index.jsp, which just redirects to calculator.jspx; calculator.jspx, which present the GUI mentioned above; and results.jspx, which displays the results. A managed bean called CalculatorController serves as the backing bean for calculator.jspx and results.jspx.

The following Figure shows a MVC view of the example Calculator application.

  1. Implement the model object Calculator.
  2. Implement the CalculatorController controller to talk to the Calculator model.
  3. Declare the calculator controller bean that gets managed by JSF in the faces-config.xml file.
  4. Declare the navigation rules in the faces-config.xml file.
  5. Create the calculator.jspx page.
  6. Create the results.jspx page.
  7. Modify the index.jsp page to redirect to calculator.jspx.

Implement the model object Calculator.

As my goal is to demonstrate how to get started with JSF, I've kept the model object very simple.
The model of this application is contained within one model object, as follows:

With that, the business logic is all set up. Your next step is to glue it to the Web application interface.

Implement the CalculatorController controller to talk to the Calculator model.

Gluing the model and view: The goal of the controller is to act as the glue from the model to the view. One function of the Controller object is to keep the model agnostic with regard to the view technology. As you can see below, the controller specifies three JavaBeans properties that will be used to collect input and display results. The properties are results (output); firstNumber (input); and secondNumber (input). The Controller also presents two operations that delegate to operations of the same name in the Calculator objects. The following listing shows the code for the CalculatorController.

package com.arcmind.jsfquickstart.controller;

import com.arcmind.jsfquickstart.model.Calculator;


/**
 * Calculator Controller
 *
 * @author $author$
 * @version $Revision$
 */
public class CalculatorController {
    //~ Instance fields --------------------------------------------------------

    /**
     * Represent the model object.
     */
    private Calculator calculator = new Calculator();

    /** First number used in operation. */
    private int firstNumber = 0;

    /** Result of operation on first number and second number. */
    private int result = 0;

    /** Second number used in operation. */
    private int secondNumber = 0;

    //~ Constructors -----------------------------------------------------------

    /**
     * Creates a new CalculatorController object.
     */
    public CalculatorController() {
        super();
    }

    //~ Methods ----------------------------------------------------------------

    /**
     * Calculator, this class represent the model.
     *
     * @param aCalculator The calculator to set.
     */
    public void setCalculator(Calculator aCalculator) {
        this.calculator = aCalculator;
    }

    /**
     * First Number property
     *
     * @param aFirstNumber first number
     */
    public void setFirstNumber(int aFirstNumber) {
        this.firstNumber = aFirstNumber;
    }

    /**
     * First number property
     *
     * @return First number.
     */
    public int getFirstNumber() {
        return firstNumber;
    }

    /**
     * Result of the operation on the first two numbers.
     *
     * @return Second Number.
     */
    public int getResult() {
        return result;
    }

    /**
     * Second number property
     *
     * @param aSecondNumber Second number.
     */
    public void setSecondNumber(int aSecondNumber) {
        this.secondNumber = aSecondNumber;
    }

    /**
     * Get second number.
     *
     * @return Second number.
     */
    public int getSecondNumber() {
        return secondNumber;
    }

    /**
     * Adds the first number and second number together.
     *
     * @return next logical outcome.
     */
    public String add() {
        
        result = calculator.add(firstNumber, secondNumber);

        return "success";
    }

    /**
     * Multiplies the first number and second number together.
     *
     * @return next logical outcome.
     */
    public String multiply() {

        result = calculator.multiply(firstNumber, secondNumber);
    	
        return "success";
    }
}

Notice in the above listing that the multiply and add methods return "success." The string success signifies a logical outcome. Note that it is not a keyword. You used the string success when specifying navigation rules in faces-config.xml; therefore, after the add or multiply operation is executed the application will forward the user to the results.jspx page.

Declare the calculator controller bean that gets managed by JSF in the faces-config.xml file.

Next, you will want to declare which beans get used by JSF GUI components. The example application only has one managed bean. It is configured in faces-config.xml as follows:

The above config tells JSF that you want to add a bean to the JSF context called CalcBean. You can call your managed bean anything you want. With the beans declared, your next step is to state the high-level navigation rules for the application.

Declare navigation rules

For this simple application you need only to establish the navigation path from the calculator.jspx page to the results.jspx page, as shown below.

The above states that if an action returns the logical outcome "success" from the /calculator.jspx view, then forward the user to the /results.jspx view.

With that, you're done configuring and writing the model and controller. Next you'll specify the our Facelets pages and component trees that represent the application view.

Edit the index.jsp page

The purpose of the index.jsp page in this application is to ensure that the /calculator.jspx page loads in the JSF context so that the page can find the corresponding view root. The index.jsp page should be edited to look as follows:

All this page does is redirect the user to calculator.jspx under the "calc" Web context. This puts the calculator.jspx page under the JSF context, where it can find its facesContext.

Create the calculator.jsp page

The calculator.jspx page is the meat of the Calculator application's view. This page takes two numbers input by the user, as shown in below.

Because creating a JSF/Facelets page can be daunting the first time, I'll show you how to build it step by step. You'll start off by declaring the taglibs for JSF and Facelets as follows:

The above tells the JSP engine that you want to use the two JSF taglibs html and core. The html taglib contains all the tags for dealing with forms and other HTML-specific goodies. The core taglib contains all the logic, validation, controller, and other tags specific to JSF. The Facelets taglib (ui) contains all Facelets tags.

Once you've laid out the page in normal HTML you want to tell the JSF system that you're going to be using JSF to manage your components. You do this by using the <f:view> tag, which informs the container that you're using JSF to manage the components contained inside of it. (When pronouncing this tag make sure you say "f colon view"; it is very important to enunciate the colon lest you offend!)

With Facelets you do not need a <f:view> as you do with JSF. Next use the <f:form> and <ui:composittion> tag as follows:

The first line above is the declaration of <ui:composition>, telling Facelets that this is a composition of components. The next line is the <h:form> putting an HTML form here. During the render phase the components contained within the form component will be looked up and asked to render themselves, whereupon they will generate standard HTML to the output.

Next, you tell JSF what other components you want in the form. Inside of the <h:form> you declare a panelGrid. A panelGrid is a composite component – that is, a component that contains other components. The panelGrid specifies the layout of the other components. The panelGrid is declared as follows:

The attribute columns being set to 3 indicates that the components will be laid out in a grid with three columns. You add six components to the panelGrid, that is, two rows. Each row consists of an outputLabel, an inputText, and a message. The label and message are associated with the inputText component; therefore, when a validation error or error message is associated with the textField, the message will show up in the message component. Both of the text fields are required, which means if their values are not present on submit an error message will be created and control will return to this view; namely /calculator.jsp.

Notice that both inputFields use a JSF EL (JavaServer Faces Expression Language) value binding for the value attribute (for example, CalcBean.firstNumber). At first blush this looks a lot like JSTL EL. However, the Universal EL code actually associates the fields with the corresponding values of the backing beans properties. This association is reflexive: that is, if firstNumber was 100 then 100 would show up when the form was displayed. Likewise, if the user submitted a valid value such as 200 then 200 would be the new value of the firstNumber property.

A more common (but also more involved) approach would be for the backing bean to expose model objects via properties and bind those model object properties to page fields. You'll see an example of this approach in later articles in the series.

In addition to the fields, the calcForm is associated with two actions using two commandButtons inside of a panelGroup, as shown below.

The panelGroup is similar in concept to the panelGrid with the exception that it lays things out differently. The command buttons use the action expression CalcBean.add to bind the button to a method on the backing bean. Thus, when the form is submitted with the button, the associated method gets invoked (assuming that all validation is ok).

And with that – whew! – you're over the biggest hump of coding a JSF application. The last couple of steps will be a breeze.

Create the results.jspx page

The results.jspx page is used to display the results of the last calculator operation. It is defined as follows:

This results.jspx file is a relatively simplistic page that displays the addition results to the user. It accomplishes this through the <h:outputText> tag. The <h:outputText> tag takes an id and value attribute. The value attribute outputs the bean value as a string when rendered. The value attribute uses JSF to bind the output value to your backing bean properties (namely, as you'll recall, firstNumber, secondNumber, and result).

It should be noted that unlike JSF with Facelets you do not need <h:outputText> tags. Why not tell you this first? You have to feel the pain of JSP before you can truly appreciate Facelets.

It is redefined as follows without the outputText tags:

Now it is smaller and more understandable.

Running our second Facelet

(At this point, this works best with Mozilla, later it won't matter.)

  1. Right click the index.jsp and Run As->Run on Server

Congrats! You are done with the first lesson!

Conclusion

If this intro to JSF, Facelets and Eclipse WTP has left you shaking your head a little, don't worry: you're over the worst hump. Getting into the conceptual framework of JSF is more than half the battle with implementing this technology – and you'll soon see that it's well worth the trouble.

This concludes the first tutorial in the JSF, Facelets, Spring, Hibernate running in Eclipse WTP series.

Where do we go from here!

There is a lot of information out there that can support you in your efforts to learn JSF, Spring, Facelets, Hibernate and Eclipse WTP.

Here are some article I wrote on JSF, Spring, Facelets and Hibernate.

JSF
*
JSF for nonbelievers: Clearing the FUD about JSF
*The JSF application lifecycle
*JSF conversion and validation
*JSF component development
*JSF is good

Facelets
*Facelets fits JSF like a Glove
*Advanced Facelets programming

Spring
*Object-relation mapping without the container
*Understanding the value of Spring
*Spring guide for managers
*ROI for Spring
*Spring Whitepaper
*Spring is good

Hibernate
*Object-relation mapping without the container

Training
*Spring Framework Training
*Hibernate Training
*JSF Training
*JavaServer Faces Training

We will revisit some of these topics as we continue with this tutorial series.

Here is the source code for this tutorial

tutorial1.zip

Where do we go from here!

There is a lot of information out there that can support you in your efforts to learn JSF, Spring, Facelets, Hibernate and Eclipse WTP.

Here are some article we wrote on JSF, Spring, Facelets and Hibernate.

JSF

Facelets

Spring

Hibernate

Training

We will revisit some of these topics as we continue with this tutorial series.

JEE WARTAC

Rick Hightower serves as chief technology officer for ArcMind Inc, a training and consulting company that specializes in JEE, JSF, Spring and Hibernate. He is coauthor of the once popular book Java Tools for Extreme Programming, about applying extreme programming to JEE development, and coauthor of Professional Struts. He writes a popular blog on JRoller called Sleepless in Tucson and is a regular contributor to IBM developerWorks. Rick is also on the editorial board of the JDJ (and has written a few JDJ editorials on JSF, Spring, EJB3, GWT, etc.) as well as a founding editor of ServerZone. Rick enjoys writing about and researching JEE, Ajax, GWT, Hibernate, JSF, Facelets, AOP and Spring. Most of all, Rick likes to write code. Rick enjoys writing about himself in the third person.

Rick. Rick. Rick. Rick. See Rick code. Code Rick! Code!

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics