Saturday, August 8, 2009

Chapters 1 & 2 Rough Cuts JSF Made Easy

Chapter 1

JSF – Getting Started

***much of this is at the end of the portlet book*

If you want to start working with JSF, the first thing you need to do is set up some sort of development environment. There are plenty of great Java development environments out there, ranging from Sun’s NetBeans to Eclipse to IBM’s various Rational Application Developer offerings. Unfortunately, I have neither the time or the patience to discuss how to configure every Java development enviroment in existence, so instead, I’m just going to describe how to get started with Java ServerFaces development with the cheapest, most simple and basic environment one could muster on a Windows based computer. If you can get a JSF application working with nothing more than Wordpad, a JDK installation, and the latest distribution of Apache’s Tomcat Servlet engine, well, you should be able to take that knowledge and apply it to just about any development environment.

So, here’s the basic minimum that you need in order to start developing and testing a JSF application on a Windows machine:

Java Development Kit, version 5 (aka 1.5) or higher

A Servlet Engine supporting servlet 2.5 and JSP 2.1 (Tomcat 6 or better will more than fit this bill)

A JSF Implementation (jsf-api.jar and jsf-impl.jar files)

The JSTL implementation jar files (standard.jar and jstl.jar)

A text editor such as Wordpad

The command prompt to compile and run our JSF applications

For this book, I have downloaded the Java Development Kit version 1.6 (Java6) with update 15. I just installed it into a directory off the root of C named _jdk1.6 After installing the JDK, don’t forget to set the JAVA_PATH environment variable to C:\_jdk1.6.

With the JDK installed, and the JAVA_PATH environment varible conifigured, you need to get going on a web based runtime environment that will allow you to deploy and test your JSF applications. Perhaps the most universally loved Servlet Engine is Tomcat, which can be found at the apache.org website.

I simply downloaded the Tomcat Core Binary distribution, version 6.0.20, and extracted the contents of the zip file to the C:\ drive. Once that was done, I renamed the folder _tomcat6. Opening a command prompt, and scooting over to the tomcat\bin directory and running startup.bat should get tomcat running. You’ll want to confirm that you’ve got a functional Tomcat instance by opening http://localhost:8080 in a web browser and making sure the Tomcat welcome page appear.

*** Do we really need sources for JSF 1.2*** xxx

Now, technically speaking, JSF is a specification. JSF is simply a document and a set of APIs and JavaDocs that describes a technology that can be used to develop web based enterprise applications in Java. To actually use JSF, you need an implementation of the JSF specification, that is, somebody must have taken the time to implement all of the things defined in the specification. Fortunately for us, Sun provides a ‘freely’ downloadable JSF implementation through what is affectionately known as the Mojarra project. A working link at the time of writing for the project is:

https://javaserverfaces.dev.java.net/ (who knows when this will change?)

From the downloads page, there are two JSF 1.2 resources you need to download, that is, the mojarra 1.2 source zip file, and the mojarra 1.2 binary zip file. Download both of these, and then unzip them to a smart location on your hard drive. I unzipped my files to C:\_jsf12

The first thing you should to after unzipping these two files is find the index.html file in the javadocs folder of the binary distribution. Bookmark that page, because you will come back to it very often. It’s nice having the JavaDocs for the JSF API on your local machine and readily accessible.

Finally, the last thing you’ll want to take note of is the lib folder in the binary download folder. This folder contains a number of resources, not the least of which are the jsf-api.jar and jsf-impl.jar files. These are the most important files in the entire JSF download, as they pretty much represent the bytecode embodiment of the implementation of the JSF specification. These two jar files will need to be added to the runtime and designtime classpaths of any JSF application that is developed and deployed.

To just test that your configuration is working, you can take the jsf-guessNumber war file and move it into the webapps folder of the tomcat6 installation. Be warned though, a few changes must be made to get this little application to work.

When the jsf-guessNumber application gets deployed, tomcat extracts the contents of the war file to a new folder in the webapps directory named appropriately, jsf-guessNumber. (Tomcat needs to be started for this extraction to happen.)

Unfortunately, the two JSF and the two JSTL jar files that are required by this app are not on the classpath. So, to get the JSF application to work, you need to create a new folder named \lib under the WEB-INF directory of the jsf-guessNumber folder that has been created in the webapps directory. Copy jsf-impl.jar, jsf-api.jar, jstl.jar and standard.jar into the lib folder you have just created, stop and restart the tomcat6 server, and then point your browser at this application when tomcat is started by using the following URL:

http://localhost:8080/jsf-guessNumber/

You will see dude there in all of his glory, asking you to pick a number between one and ten. Go ahead and play! It means your tomcat server, and your JSF files, are all working properly together.

l

Chapter 21

A Simple JSF Application

Let’s put together a very simple JSF application, using the opportunity to examine the structure of a JSF application, while at the same time, testing our ability to create and deploy applications to our test environment.

JSF applications are simply standard web applications that conform to the requirements of the Servlet and JSP specifications. As such, every JSF application needs an application root. For this book, I’m going to create a new folder off of the root of C:\ named _easyjsf that will act as the root of my JSF application. C:\_easyjsf

Under the root of a Java web application there is always a folder named WEB-INF, and that folder must always containt a deployment descriptor for the web application named web.xml. This web.xml file provides information to the runtime environment, such as tomcat or any other servlet engine, information about how to configure the environment in which the application will run.

Now, JSF isn’t a built in feature of a servlet engine, and it’s certainly not part of the Servlet and JSP specification. So, if you want to create a web application that will leverage JSF technology, you need to add the various jar files that provide an implementation of the JSF specification. Furthermore, these jar files need to go in a very specific directory – a directory named lib that resides directly under the WEB-INF folder of your web application.

The four jar files that need to go in this folder are:

jsf-api.jar

jsf-impl.jar

jstl.jar

standard.jar

The jsf-api.jar and jsf-impl.jar files were downloaded from Sun as part of the binary JSF distribution zip file. The jstl.jar and standard.jar files can either be downloaded from apache.org, or more easily, they can be found in the lib folder of various sample applications that are also included in the binary JSF distribution obtained from Sun.

Furthermore, any Java code that gets compiled and distributed with your JSF application will go in a classes directory that also resides under the WEB-INF folder. Although we won’t have any compiled Java code in this example, it is worthwhile adding in the classes folder while we’re puttering around in WEB-INF.

For a JSF application, the web.xml file can be pretty lean, after all, there’s a special file named faces-config.xml that contains all of the JSF centric configuration data. However, there are two extremely important parts of a web.xml file that pertain to JSF.

The web.xml file of a JSF application must reference the FacesServlet. In a JSF application, all JSF centric requests go through a single, central Servlet which is uncreatively named FacesServlet. All JSF centric requests that come into a given web based application are routed through this single, monolithic servlet, which then is responsible for handling the incoming request, and generating a response that will get sent back to the client:

<servlet id="JSF_Front_Controller_Servlet">

<servlet-name>Faces Servlet</servlet-name>

<servlet-class>
javax.faces.webapp.FacesServlet
</servlet-class>

</servlet>

Now, I mentioned that the all JSF centric requests that come into a given web application go through the FacesServlet. However, that begs the question, “how does a given application know that an incoming request is a JSF centric request?” Well, that’s an easy question to answer.

In a web application, all JSF based requests will share a common extension. So, rather than requesting a .jsp file, or an .html file, JSF requests will end with an extension such as .faces. This is known as an ‘extension mapping’ or a ‘servlet mapping’, and like the mapping of the FacesServlet, the mapping of requests having a given file extension back to the FacesServlet, is configured in the deployment descriptor of the web application.

<servlet-mapping>

<servlet-name>Faces Servlet</servlet-name>

<url-pattern>*.faces</url-pattern>

</servlet-mapping>

Notice how the servlet-name in the <servlet-mapping>, Faces Servlet, matches the exact name used when configuring the FacesServlet in the <servlet> entry of the web.xml file.

Along with the <servlet> and <servlet-mapping> entries, the web.xml file should include a <display-name> element. We’re just going to use the simple display name of JSFWeb

<display-name>JSFWeb</display-name>

All of the elements, starting with the <display-name> tag, and ending with the <servlet-mapping> go within a fairly verbose <web-app> tag that includes version, schema name, and schema location elements. As I said, it’s fairly verbose, and typing it out by hand is simply insane. If you look at the various web.xml files that are in the WEB-INF folder of the various sample applications that come with the JSF binaries, you’ll find plenty of examples of the web-app entry that you can copy and paste into your own deployment descriptor.

Also notice the ?xml element at the top of the file.

<?xml version='1.0' encoding='UTF-8'?>

<web-app
version="2.5"

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-app_2_5.xsd">

<display-name>JSFWeb</display-name>

<servlet id="JSF_Front_Controller_Servlet">

<servlet-name>Faces Servlet</servlet-name>

<servlet-class>

javax.faces.webapp.FacesServlet

</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>Faces Servlet</servlet-name>

<url-pattern>*.faces</url-pattern>

</servlet-mapping>

</web-app>

Alongside the web.xml file, any JSF application also needs a faces-config.xml file stored right there in the WEB-INF folder. As the name implies, the faces-config.xml file contains a variety of salacious nuggets of information about your JSF application, and as your application grows, so does the number of elements and entries within the faces-config.xml file. For now, however, our faces-config.xml file will be pretty much nascent, with nothing more than the <?xml> entry, and the top level <faces-config> tag, along with the verbose and intimidating namespace, version, and schema location attributes. Again, these faces-config attributes are so long and tedious, it’s practically impossible to type them out by hand without some type of mistake. It’s best to just copy the full <faces-config> element and attributes from one of the sample applications that get extracted from the binary distribution of the JSF implementation that was downloaded from Sun in the previous chapter.

The simple JSP page

With the basic configuration stuff done, it’s time to write a little ‘Hello World’ page that will get served up by the JSF framework that we have so diligently set up. We’re not going to win any programming awards with this rudimentary JSF page, but it will introduce a few basics to us, and it will also help verify that indeed, we can get a basic JSF page working in our local environment.

<%@taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<html>
<head>
<title>Simple JSF Page</title>

</head>
<f:view>
    <body>
    <p>Hello World!</p>
    </body>
</f:view>
</html>

So, there’s really nothing too intimidating here.

First of all, we see a taglib declaration at the start of the page. There are two tag library sets provided by the JSF framework, the first of which is the ‘core’ library, and the other is the ‘html’ tag library. This little ‘Hello World’ page is only going to use one JSF tag, the <f:view> tag, and since that tag is in the ‘core’ taglibrary module, only the core taglibrary, which by convention uses the prefix ‘f’, needs to be declared at the top of the page.

Following the taglib declaration we have standard HTML tags, namely the <html> tag itself, and a header tag which contains the page title. The page is simply titled “Simple JSF Page.”

Of course, the guts of this html page is the body that gets displayed in the web browser, and one of the rules of JSF development is that any visual elements that exist on a webpage need to be enclosed within a <f:view> tag. You’ll notice that in this example, the <f:view> tag surrounds theentire body, ending after the ‘body close’ tag, </body>, and just before the end html tag. </html>

Inside the body of the page, we don’t have anything earth shattering. All we have is a little “Hello World” declaration surrounded by paragraph tags. As I said, this isn’t going to win us any programming awards, but it is going to help verify the veracity of our test environment.

Type this code into any standard text editor, such as Microsoft’s Wordpad, and save the file as helloworld.jsp in the application root folder, which for me, is C:\_easyjsf. Now, remember, we save the file as helloworld.jsp, NOT helloworld.jsf!

By the way, it’s a good idea to keep our pages as xHTML compliant as possible. As a good housekeeping measure, and to keep our pages xHTML compliant, it’s not a bad idea to put the following doctype tag at the top of our helloworld.jsp:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

With your application configured and your helloworld.jsp file coded and saved to the root of your web application, it’s time to ‘war up’ your JSF application. A war file, or web application archive, is the standard format for distributing and deploying J2EE/JEE web based applications.

The jar utility that comes with the JDK is great at compressing your web applications into war files that can be deployed directly to Tomcat. To war up your application, simply navigate a command prompt to the C:\_easyjsf> folder, and issue the following command:

C:\_easyjsf>C:\_jdk1.6\bin\jar -cvf easyjsf.war *.*

Now, this relies on the fact that the JDK has been installed into C:\_jdk1.6. If you have a different folder location, you will need to reference that JDK intallation folder explicitly. Alternatively, you could also just use the JAVA_HOME environment variable as so:

C:\_easyjsf>%JAVA_HOME%\bin\jar -cvf easyjsf.war *.*

Regardless of how you run the command, once the command is issued successfully, a war file will be created in the application root, named easyjsf.war. Copy this file to the webapps directory of your Tomcat server, start your Tomcat server if it is not already started, and wait a moment for the application to be deployed.

Looking at the log file from tomcat, you should see some information about the JSF 1.2 context being successfully initialized for your easyjsf application. (You may need to stop and start your Tomcat server to have the application loaded properly the first time.)

INFO: Initializing Mojarra (1.2_13-b01-FCS) for context '/easyjsf'

Aug 8, 2009 9:21:16 PM org.apache.catalina.startup.HostConfig deployWAR

INFO: Deploying web application archive ifnavigation.war

Aug 8, 2009 9:21:16 PM com.sun.faces.config.WebConfiguration processInitParameters

With the context successfully initialized, it’s time to navigate to your JSF application. You can invoke your application using the following URL:

http://localhost:8080/easyjsf/helloworld.faces

The key elements here are the ip address and port (localhose:8080), the context root, which is easyjsf, which matches the name of the war file (minus the .war extension), and then the name of the JSP we are invoking. However, you should notice that the url says helloworld.faces, not helloworld.jsp.

Remember, for our application, only requests that end with the .faces extension are handled by the FacesServlet, and subsequently, the Java ServerFaces framework. By putting the .faces extension on our URL, the JSF framework knows to locate a resource named helloworld, which in this case, is our helloworld.jsp, and as a result, we see our little ‘Hello World’ message in the web browser.

Alternatively, if we tried to access the jsp directly, we’d get all sorts of esoteric errors. Here’s what I got when I tried to invoke our jsp by name with the following URL:

http://localhost:8080/easyjsf/helloworld.jsp

The server encountered an internal error...

JasperException: An exception occurred at line 8

5: <title>Simple JSF Page</title> 6: 7: </head> 8: <f:view> 9: <body> 10: <p>Hello World!</p> 11: </body>

Stacktrace: JspServletWrapper.handleJspException(JspServletWrapper.java:505)

JspServletWrapper.service(JspServletWrapper.java:416)

root cause

java.lang.RuntimeException: Cannot find FacesContext

UIComponentClassicTagBase.getFacesContext

1 comment:

  1. This tutorial covers JSF 2.0 using the Mojarra JSF 2.0 implementation, but the the JSF 1.x tutorial covers JSF 1 with Apache MyFaces. Click on a topic below to get the detailed tutorial or download the source code. The examples here were developed and deployed on Tomcat, but they will run on any Java server that supports servlets 2.5 or later.

    heilkräuter

    ReplyDelete

Followers