Java EE 7 Recipes

xgb3

贡献于2013-12-17

字数:0 关键词: J2EE Java开发 Java

For your convenience Apress has placed some of the front matter material after the index. Please use the Bookmarks and Contents at a Glance links to access them. v Contents at a Glance About the Author ���������������������������������������������������������������������������������������������������������� xxxvii About the Technical Reviewers ������������������������������������������������������������������������������������� xxxix Acknowledgments ��������������������������������������������������������������������������������������������������������������xli Introduction ����������������������������������������������������������������������������������������������������������������������xliii Chapter 1: Introduction to Servlets■■ �����������������������������������������������������������������������������������1 Chapter 2: JavaServer Pages■■ ������������������������������������������������������������������������������������������53 Chapter 3: The Basics of JavaServer Faces■■ ��������������������������������������������������������������������97 Chapter 4: Facelets■■ ��������������������������������������������������������������������������������������������������������159 Chapter 5: JavaServer Faces Standard Components■■ ����������������������������������������������������199 Chapter 6: Advanced JavaServer Faces and Ajax■■ ���������������������������������������������������������255 Chapter 7: JDBC■■ �������������������������������������������������������������������������������������������������������������317 Chapter 8: Object-Relational Mapping■■ ��������������������������������������������������������������������������369 Chapter 9: Enterprise JavaBeans■■ ����������������������������������������������������������������������������������409 Chapter 10: The Query API and JPQL■■ �����������������������������������������������������������������������������447 Chapter 11: Oracle’s GlassFish■■ ��������������������������������������������������������������������������������������471 Chapter 12: Contexts and Dependency Injection■■ �����������������������������������������������������������497 Chapter 13: Java Message Service■■ �������������������������������������������������������������������������������517 Chapter 14: Authentication and Security■■ ����������������������������������������������������������������������537 Chapter 15: Java Web Services■■ �������������������������������������������������������������������������������������563 Chapter 16: Enterprise Solutions Using Alternative Programming Languages■■ ���������������597 ■ Contents at a Glance vi Chapter 17: WebSockets and JSON-P■■ ����������������������������������������������������������������������������605 Chapter 18: JavaFX in the Enterprise■■ ����������������������������������������������������������������������������615 Chapter 19: Concurrency and Batch Applications■■ ���������������������������������������������������������647 Appendix A: Java EE Development with NetBeans IDE■■ ��������������������������������������������������671 Index ���������������������������������������������������������������������������������������������������������������������������������683 xliii Introduction The Java platform is one of the most widely used platforms for application development in the world. The platform is so popular, that there are several different flavors of Java that can be used for developing applications that run on different mediums. From development of desktop or mobile, to web applications and hardware operating systems, Java can be utilized for development of just about any solution. As such, Java has become a very popular platform for development of enterprise applications, offering web services, reliability, security, and much more. Java Enterprise Edition was originally released in 1999 as Java 2 Platform, Enterprise Edition (J2EE). Although several enterprise frameworks were available for development of reliable and secure applications on the Java platform, it made sense to standardize some solutions in order to minimize customization and help to make Java Enterprise development more prevalent in the industry. The platform originally included a terse number of specifications for standardization, including Java Servlet, JavaServer Pages, RMI, Java Database Connectivity (JDBC), Java Message Service API (JMS), Java Transaction API (JTA), and Enterprise JavaBeans. Development of J2EE applications had a large learning curve, and it was cumbersome because it required the use of XML for lots of configuration. Even with these setbacks, it became popular amongst larger organizations and companies due to the prevalence of Java and its well-known security benefits. In 2001, J2EE 1.3 was released, adding more specifications to the platform, including the JavaServer Pages Standard Tag Library (JSTL) and Java Authentication and Authorization Service (JAAS). Other specifications, such as Java Servlet, also gained enhancements under the J2EE 1.3 release, making evolutionary enhancements to the platform. The release of J2EE 1.4 in 2003 marked a major milestone for Java Enterprise, as many new specifications were added to the platform, providing standards for even more Java technologies. The release of J2EE 1.4 marked the first iteration of Web Services for J2EE 1.1, JavaServer Faces (JSF), and Java APIs for XML solutions such as JAXP, JAXR, and more. Although the release of J2EE 1.4 included many specifications, it was still deemed as “difficult to learn” and “cumbersome.” Over the next few years, J2EE was reworked in an attempt to make it easier to learn and utilize. Although XML is an excellent means for configuration, it can be cumbersome and hard to manage, so configuration was a big item that was addressed for the next release. Technologies such as Enterprise JavaBeans (EJB) included some redundant characteristics, making EJB coding time-consuming and difficult to manage, so an overhaul of EJB was also in order. In May of 2006, Java EE 5 was released, leaving the J2EE acronym behind, and changing to simply Java EE. The Java EE 5 platform was significantly easier to use and maintain because features such as annotations were introduced, cutting down the amount of XML configuration significantly. EJBs were made easier to develop, making EJB a marketable technology for object-relational mapping once again. Java Enterprise Edition has since become a widely adopted and mature platform for enterprise development. Java EE 6 was released in 2009, making configuration and technologies even easier, and adding more specifications to the platform. Specifications such as Contexts and Dependency Injection and Bean Validation were introduced, making usability even easier and development more productive. This latest release, Java EE 7, enhances the platform even more by adding new specifications such as WebSockets and JSON-P. Specifications such as JSF and EJB were enhanced, adding even more features to increase productivity and functionality. This book focuses on Java Enterprise as a whole, covering most of the widely used specifications that make up Java EE. You will learn how to make use of each of the major specifications, through real-world examples and solutions. This book will cover APIs that have not been updated for Java EE 7, as well as those that have been enhanced, providing complete coverage for those who are newer to the platform. It also features recipes that cover the newest features of the platform, so that seasoned Java EE developers can skip those introductory concepts and delve into newer material. ■ Introduction xliv I work with Java Enterprise on a daily basis, and I have a deep passion for the technologies involved in the platform. I hope that this book increases your passion of Java EE and the Java platform in its entirety. Who This Book Is For This book is intended for all those who are interested in learning Java Enterprise Edition (Java EE) development and/ or already know Java EE but would like some information regarding the new features included in Java EE 7. Those who are new to Java EE development can read this book, and it will allow them to start from scratch to get up and running quickly. Intermediate and advanced Java developers who are looking to update their arsenal with the latest features that Java EE 7 has to offer can also read the book to quickly update and refresh their skill sets. How This Book Is Structured This book is structured so that it does not have to be read from cover to cover. In fact, it is structured so that developers can chose which topic(s) they’d like to read about and jump right to them. Each recipe contains a problem to solve, one or more solutions to solve that problem, and a detailed explanation of how the solution works. Although some recipes may build upon concepts that have been discussed in other recipes, they will contain the appropriate references so that the developer can find other related recipes that are beneficial to the solution. The book is designed to allow developers to get up and running quickly with a solution, so that they can be home in time for dinner. Conventions Throughout the book, I’ve kept a consistent style for presenting Java code, SQL, command-line text, and results. Where pieces of code, SQL, reserved words, or code fragments are presented in the text, they are presented in fixed-width Courier font, such as this (working) example: public class MyExample { public static void main(String[] args){ System.out.println("Java EE 7 is excellent!"); } } Downloading the Code The code for the examples shown in this book is available on the Apress web site, www.apress.com. A link can be found on the book’s information page under the Source Code/Downloads tab. This tab is located underneath the “Related Titles” section of the page. Note■■ the sources for this book may change over time to provide new implementations that incorporate the most up-to-date features in Java EE. That said, if any issues are found within the sources, please submit them via the Apress web site “Errata” form, and code will be adjusted accordingly. ■ Introduction xlv Configuring a Database for the Book Sources This book’s sources have been developed using the Apache Derby database, which ships with NetBeans IDE and GlassFish. The book sources have also been optimized for use with an Oracle 11g database. Please install and configure the database for use with the book sources using either of those database choices prior to working with the sources. The database configuration involves creation of a database schema or user, as well as execution of the create_database.sql script (contained within the book sources) that goes along with the database of your choice. You must also place the appropriate database JDBC driver into the GlassFish CLASSPATH. You can do this by copying the ojdbc6.jar (Oracle) or derbyclient.jar (Apache Derby) JAR file into your Integrated Development Environment (IDE) project for the book sources, or into the \glassfish4\domains\domain1\lib\ext directory. If copying into the GlassFish lib directory, then once the JAR file has been copied into place, the GlassFish server will need to be restarted, if it is already running. Once the database has been installed/configured, and the SQL scripts contained within the book sources have been executed, please log into the GlassFish administrative console and set up a database connection pool to work with the database of your choice. For more information, please see Recipe 11-5. After a connection pool has been configured, please update the persistence.xml file that is contained within the book sources accordingly, so that the data source name aligns with the one you’ve assigned to the GlassFish JDBC resource. Setting Up a NetBeans Project Before setting up a NetBeans project for the book sources, please install and configure GlassFish v4 accordingly. For more information, please see Recipe 11-1. Note■■   Before setting up a NetBeans project for the book sources, please install and/or configure Apache Derby or Oracle Database accordingly. A note regarding dependencies: this project depends upon the use of the third-party PrimeFaces library. At the time of this book publication, the PrimeFaces 4.0 release was not yet available to the public. That said, the sources can be obtained from the Google Code repository, and the dependency JAR can be built from the sources. Please see the Google Code repository at http://code.google.com/p/primefaces/source/checkout. Please perform the following steps to set up the NetBeans project: 1. Open NetBeans IDE 7.3 or greater. 2. Choose the File ➤ New Project ➤ Java Web ➤ Web Application menu option. 3. Title the project JavaEERecipes and choose a desired Project Location. 4. Server and Settings: a. If you have not yet registered your GlassFish v4 server with NetBeans, please click the Add button in this dialog, and add the server. To do so, you will need to know the location of the GlassFish server on your file system. b. Java EE Version: Java EE 7 Web. 5. Frameworks: a. Select JavaServer Faces, and then accept all defaults. ■ Introduction xlvi 6. Click Finish. 7. Go to your file system and copy the contents from within the JavaEERecipes-BookSources\ NBProject\src directory into your new NetBeans project src directory. 8. Add the required library dependencies to your project by right-clicking the project and choosing the Properties option. Once the Properties dialog is open, select the Libraries, and add the following dependencies: a. Jython 2.5.3 or later b. Groovy 2.0.1 or later c. PrimeFaces 4.0 or later d. Database JDBC JAR file, if not already placed within the GlassFis0h lib directory 1 Chapter 1 Introduction to Servlets Java servlets were the first technology for producing dynamic Java web applications. Sun Microsystems released the first Java Servlet specification in 1997. Since then it has undergone tremendous change, making it more powerful and easing development more with each release. The 3.0 version was released as part of Java EE 6 in December 2009. Servlets are at the base of all Java EE applications. Although many developers use servlet frameworks such as Java Server Pages (JSP) and Java Server Faces (JSF), both of those technologies compile pages into Java servlets behind the scenes via the servlet container. That said, a fundamental knowledge of Java servlet technology could be very useful for any Java web developer. Servlets are Java classes that conform to the Java Servlet API, which allows a Java class to respond to requests. Although servlets can respond to any type of request, they are most commonly written to respond to web-based requests. A servlet must be deployed to a Java servlet container in order to become usable. The Servlet API provides a number of objects that are used to enable the functionality of a servlet within a web container. Such objects include the request and response objects, pageContext, and a great deal of others, and when these objects are used properly, they enable a Java servlet to perform just about any task a web-based application needs to do. As mentioned, servlets can produce not only static content but also dynamic content. Since a servlet is written in Java, any valid Java code can be used within the body of the servlet class. This empowers Java servlets and allows them to interact with other Java classes, the web container, the underlying file server, and much more. This chapter will get you started developing and deploying servlets. You will learn how to install Oracle’s GlassFish application server, a robust servlet container, which will enable you to deploy sophisticated Java enterprise applications. You will be taught the basics of developing servlets, how to use them with client web sessions, and how to link a servlet to another application. All the while, you will learn to use standards from the latest release of the Java Servlet API, which modernizes servlet development and makes it much easier and more productive than in years past. Note■■   You can run the examples within this chapter by deploying the JavaEERecipes.war file (contained in the sources) to a local Java EE application server container such as GlassFish v4. You can also set up the NetBeans project entitled JavaEERecipes that is contained in the sources, build it, and deploy to GlassFish v4. Otherwise, you can run the examples in Chapter 1 stand-alone using the instructions provided in Recipe 1-3. If you deploy the JavaEERecipes.war file to a Java EE application server container, you can visit the following URL to load the examples for this chapter: http://localhost:8080/JavaEERecipes/faces/chapter01/index.xhtml. Chapter 1 ■ Introduction to Servlets 2 1-1. Setting Up a Java Enterprise Environment Problem You want to set up an environment that you can use to deploy and run Java servlets and other Java enterprise technologies. Solution Download and install Oracle’s GlassFish application server from the GlassFish web site. The version used for this book is the open source edition, release 4.0, and it can be downloaded from http://glassfish.java.net/ in the “Download” section. Select the .zip or .tar.gz download format, and decompress the downloaded files within a directory on your workstation. I will refer to that directory as /JAVA_DEV/Glassfish. The GlassFish distribution comes prepackaged with a domain so that developers can get up and running quickly. Once the .zip file has been unpacked, you can start the domain by opening a command prompt or terminal and starting GlassFish using the following statement:   /PATH_TO_GLASSFISH/Glassfish/bin/asadmin start-domain domain1   The domain will start, and it will be ready for use. You will see output from the server that looks similar to the following:   Waiting for domain1 to start ............ Successfully started the domain : domain1 domain Location: /PATH_TO_GLASSFISH/glassfish/domains/domain1 Log File: /PATH_TO_GLASSFISH/glassfish/domains/domain1/logs/server.log Admin Port: 4848 Command start-domain executed successfully.  How It Works The development of Java EE applications begins with a Java EE–compliant application server. A Java EE–compliant server contains all the essential components to provide a robust environment for deploying and hosting enterprise Java applications. The GlassFish application server is the industry standard for Java EE 7, and there are two versions of the server: open source, and licensed by Oracle. For the purposes of this book, the open source edition will be used. However, in a production environment, you may want to consider using the Oracle-licensed version so that technical support will be available if needed. Installing GlassFish is easy. It consists of downloading an archive and uncompressing it on your development machine. Once you’ve completed this, the application server will make use of your locally installed Java development kit (JDK) when it is started. Once the server starts, you can open a browser and go to http://localhost:4848 to gain access to the GlassFish administrative console. Most Java EE developers who deploy on GlassFish use the administrative console often. The administrative console provides developers with the tools needed to deploy web applications, register databases with Java Naming and Directory Interface (JNDI), set up security realms for a domain, and do much more. To access the GlassFish administrative console for the first time, use the user name of admin and the password of adminadmin. You should take some time to become familiar with the administrative console because the more you know about it, the easier it will be to maintain your Java EE environment. Installing the GlassFish application server is the first step toward developing Java applications for the enterprise. While other applications servers such as JBoss, Apache TomEE, and WebLogic are very well adopted, GlassFish offers developers a solid environment that is suitable for production use and easy to learn. It also has the bonus of being an open source application server and the reference implementation for Java EE 7. Chapter 1 ■ Introduction to Servlets 3 1-2. Developing a Servlet Problem You want to develop a web page that enables you to include dynamic content. Solution Develop a Java servlet class, and compile it to run within a Java servlet container. In this example, a simple servlet is created that will display some dynamic content to the web page. The following is the servlet code that contains the functionality for the servlet:   package org.javaeerecipes.chapter01.recipe01_02;   import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   /** * Recipe 1-2: Developing a Servlet * @author juneau */ public class SimpleServlet extends HttpServlet {   /** * Processes requests for both HTTP * GET and * POST methods. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { // Place page output here out.println(""); out.println(""); out.println("Servlet SimpleServlet"); out.println(""); out.println(""); out.println("

Servlet SimpleServlet at " + request.getContextPath() + "

"); out.println("
Welcome to Java EE Recipes!"); ChaptER 1 ■ INtROdUCtION tO SERvLEtS 4 out.println(""); out.println(""); } finally { out.close(); } } /** * Handles the HTTP GET * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handles the HTTP POST * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Returns a short description of the servlet for documentation purposes. * * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; }// } The following code is the web deployment descriptor. This file is required for application deployment to a servlet container. It contains the servlet configuration and mapping that maps the servlet to a URL. In Recipe 1-4 you will learn how to omit the servlet configuration and mapping from the web.xml file to make servlet development, deployment, and maintenance easier. Chapter 1 ■ Introduction to Servlets 5 SimpleServlet org.javaeerecipes.chapter1.recipe01_02.SimpleServlet SimpleServlet /SimpleServlet /SimpleServlet   Note■■   Many web applications use a page named index.html or index.xhtml as their welcome file. There is nothing wrong with doing that, and as a matter of fact, it is the correct thing to do. The use of /SimpleServlet as the welcome file in this example is to make it easier to follow for demonstration purposes. To compile the Java servlet, use the javac command-line utility. The following line was excerpted from the command line, and it compiles the SimpleServlet.java file into a class file. First, traverse into the directory containing the SimpleServlet.java file; then, execute the following:   javac -cp /JAVA_DEV/Glassfish/glassfish/modules/javax.servlet-api.jar SimpleServlet.java   Once the servlet code has been compiled into a Java class file, it is ready to package for deployment. Note■■   You may want to consider installing a Java integrated development environment (IDE) to increase your development productivity. There are several very good IDEs available to developers, so be sure to choose one that contains the features you find most important and useful for development. As the author of this book on Java EE 7, I recommend installing Net- Beans 7.3 or newer for development. NetBeans is an open source IDE that is maintained by Oracle, and it includes support for all the cutting-edge features that the Java industry has to offer, including EJB development with Java EE 7, JavaFX 2.0 support, and more. To learn more about working with NetBeans and Java EE 7, please see the appendix of this book. How It Works Java servlets provide developers with the flexibility to design applications using a request-response programming model. Servlets play a key role in the development of service-oriented and web application development on the Java platform. Different types of servlets can be created, and each of them is geared toward providing different functionality. The first type is the GenericServlet, which provides services and functionality. The second type, Chapter 1 ■ Introduction to Servlets 6 HttpServlet, is a subclass of GenericServlet, and servlets of this type provide functionality and a response that uses HTTP. The solution to this recipe demonstrates the latter type of servlet because it displays a result for the user to see within a web browser. Servlets conform to a life cycle for processing requests and posting results. First, the Java servlet container calls the servlet’s constructor. The constructor of every servlet must take no arguments. Next, the container calls the servlet init method, which is responsible for initializing the servlet. Once the servlet has been initialized, it is ready for use. At that point, the servlet can begin processing. Each servlet contains a service method, which handles the requests being made and dispatches them to the appropriate methods for request handling. Implementing the service method is optional. Finally, the container calls the servlet’s destroy method, which takes care of finalizing the servlet and taking it out of service. Every servlet class must implement the javax.servlet.Servlet interface or extend another class that does. In the solution to this recipe, the servlet named SimpleServlet extends the HttpServlet class, which provides methods for handling HTTP processes. In this scenario, a browser client request is sent from the container to the servlet; then the servlet service method dispatches the HttpServletRequest object to the appropriate method provided by HttpServlet. Namely, the HttpServlet class provides the doGet, doPut, doPost, and doDelete methods for working with an HTTP request. The HttpServlet class is abstract, so it must be subclassed, and then an implementation can be provided for its methods. In the solution to this recipe, the doGet method is implemented, and the responsibility of processing is passed to the processRequest method, which writes a response to the browser using the PrintWriter. Table 1-1 describes each of the methods available to an HttpServlet. Table 1-1.  HttpServlet Methods Method Name Description doGet Used to process HTTP GET requests. Input sent to the servlet must be included in the URL address. For example: ?myName=Josh&myBook=JavaEERecipes. doPost Used to process HTTP POST requests. Input can be sent to the servlet within HTML form fields. See Recipe 1-7 for an example. doPut Used to process HTTP PUT requests. doDelete Used to process HTTP DELETE requests. doHead Used to process HTTP HEAD requests. doOptions Called by the container to allow OPTIONS request handling. doTrace Called by the container to handle TRACE requests. getLastModified Returns the time that the HttpServletRequest object was last modified. init Initializes the servlet. destroy Finalizes the servlet. getServletInfo Provides information regarding the servlet. A servlet generally performs some processing within the implementation of its methods and then returns a response to the client. The HttpServletRequest object can be used to process arguments that are sent via the request. For instance, if an HTML form contains some input fields that are sent to the server, those fields would be contained within the HttpServletRequest object. The HttpServletResponse object is used to send responses to the client browser. Both the doGet and doPost methods within a servlet accept the same arguments, namely, the HttpServletRequest and HttpServletResponse objects. Chapter 1 ■ Introduction to Servlets 7 Note■■ the doGet method is used to intercept HTTP GET requests, and doPost is used to intercept HTTP POST requests. Generally, the doGet method is used to prepare a request before displaying for a client, and the doPost method is used to process a request and gather information from an HTML form. In the solution to this recipe, both the doGet and doPost methods pass the HttpServletRequest and HttpServletResponse objects to the processRequest method for further processing. The HttpServletResponse object is used to set the content type of the response and to obtain a handle on the PrintWriter object in the processRequest method. The following lines of code show how this is done, assuming that the identifier referencing the HttpServletResponse object is response:   response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter();   A GenericServlet can be used for providing services to web applications. This type of servlet is oftentimes used for logging events because it implements the log method. A GenericServlet implements both the Servlet and ServletConfig interfaces, and to write a generic servlet, only the service method must be overridden. 1-3. Packaging, Compiling, and Deploying a Servlet Problem You have written a Java servlet and now want to package it and deploy it for use. Solution Compile the sources, set up a deployable application, and copy the contents into the GlassFish deployment directory. From the command line, use the javac command to compile the sources.   javac -cp /PATH_TO_GLASSFISH/Glassfish/glassfish/modules/javax.servlet-api.jar SimpleServlet.java   After the class has been compiled, deploy it along with the web.xml deployment descriptor, conforming to the appropriate directory structure. QUICK START  To quickly get started with packaging, compiling, and deploying the example application for the servlet recipes in this chapter on GlassFish or other servlet containers such as Apache Tomcat, follow these steps: 1. Create a single application named SimpleServlet by making a directory named SimpleServlet. 2. Create the WEB-INF, WEB-INF/classes, and WEB-INF/lib directories inside SimpleServlet. 3. drag the Chapter 1 sources (beginning with the org directory) in the WEB-INF/classes directory you created, as well as the contents of the web folder, into the root of your SimpleServlet directory. Chapter 1 ■ Introduction to Servlets 8 4. Copy the web.xml file that is in the source’s recipe01_02 directory into the WEB-INF directory you created. 5. download the JavaMail API code from Oracle, and copy the mail.jar file from the download into the WEB-INF/lib directory you created. This API will be used to send mail in future recipes. 6. Set your CLASSPATH to include the mail.jar file you downloaded in step 5. 7. at the command prompt, change directories so that you are in the classes directory you created in step 2. Compile each recipe with the command javac org\javaeerecipes\ chapter01\recipe1_x\*.java, where x is equal to the recipe number. 8. Copy your SimpleServlet application directory to the /JAVA_DEV/Glassfish/ glassfish/domains/domain1/autodeploy directory for GlassFish or the /Tomcat/webapps directory for Tomcat. Test the application by launching a browser and going to http://localhost:8080/SimpleServlet/servlet_name, where servlet_name corresponds to the servlet name in each recipe. If using Tomcat, you may need to restart the server in order for the application to deploy. How It Works To compile the sources, you can use your favorite Java IDE such as NetBeans or Eclipse, or you can use the command line. For the purposes of this recipe, I will do just that. If you’re using the command line, you must ensure you are using the javac command that is associated with the same Java release that you will be using to run your servlet container. In this example, we will say that the location of the Java SE 7 installation is at the following path:   /Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home   This path may differ in your environment if you are using a different operating system and/or installation location. To ensure you are using the Java runtime that is located at this path, set the JAVA_HOME environment variable equal to this path. On OS X and *nix operating systems, you can set the environment variable by opening the terminal and typing the following:   export JAVA_HOME=/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home   If you are using Windows, use the SET command within the command line to set up the JAVA_HOME environment variable.   set JAVA_HOME=C:\your-java-se-path\   Next, compile your Java servlet sources, and be sure to include the javax.servlet-api.jar file that is packaged with your servlet container (use servlet-api.jar for Tomcat) in your CLASSPATH. You can set the CLASSPATH by using the –cp flag of the javac command. The following command should be executed at the command line from within the same directory that contains the sources. In this case, the source file is named SimpleServlet.java.   javac -cp /path_to_jar/javax.servlet-api.jar SimpleServlet.java   Chapter 1 ■ Introduction to Servlets 9 Next, package your application by creating a directory and naming it after your application. In this case, create a directory and name it SimpleServlet. Within that directory, create another directory named WEB-INF. Traverse into the WEB-INF directory, and create another directory named classes. Lastly, create directories within the classes directory in order to replicate your Java servlet package structure. For this recipe, the SimpleServlet.java class resides within the Java package org.javaeerecipes.chapter01.recipe01_02, so create a directory for each of those packages within the classes directory. Create another directory within WEB-INF and name it lib; any JAR files containing external libraries should be placed within the lib directory. In the end, your directory structure should resemble the following:   SimpleServlet |_WEB-INF |_classes |_org |_javaeerecipes |_chapter01 |_recipe01_02 |_lib   Place your web.xml deployment descriptor within the WEB-INF directory, and place the compiled SimpleServlet.class file within the recipe01_02 directory. The entire contents of the SimpleServlet directory can now be copied within the deployment directory for your application server container to deploy the application. Restart the application server if using Tomcat, and visit the URL http://localhost:8080/SimpleServlet/SimpleServlet to see the servlet in action. 1-4. Registering Servlets Without WEB-XML Problem Registering servlets in the web.xml file is cumbersome, and you want to deploy servlets without modifying web.xml at all. Solution Use the @WebServlet annotation to register the servlet, and omit the web.xml registration. This will alleviate the need to modify the web.xml file each time a servlet is added to your application. The following adaptation of the SimpleServlet class that was used in Recipe 1-2 includes the @WebServlet annotation and demonstrates its use:   package org.javaeerecipes.chapter01.recipe01_04;   import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   Chapter 1 ■ Introduction to Servlets 10 /** * Recipe 1-4 - Registering Servlets without WEB-XML * @author juneau */ @WebServlet(name = "SimpleServletNoDescriptor", urlPatterns = {"/SimpleServletNoDescriptor"}) public class SimpleServletNoDescriptor extends HttpServlet {   /** * Processes requests for both HTTP * GET and * POST methods. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { /* * TODO output your page here. You may use following sample code. */ out.println(""); out.println(""); out.println("Servlet SimpleServlet"); out.println(""); out.println(""); out.println("

Servlet SimpleServlet at " + request.getContextPath() + "

"); out.println("
Look ma, no WEB-XML!"); out.println(""); out.println(""); } finally { out.close(); } }   /** * Handles the HTTP GET method. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); }   Chapter 1 ■ Introduction to Servlets 11 /** * Handles the HTTP POST method. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); }   }   In the end, the servlet will be accessible via a URL in the same way that it would if the servlet were registered within web.xml. Note■■   Remove the existing servlet mapping within the web.xml file in order to make use of the @WebServlet annotation. How It Works There are a couple of ways to register servlets with a web container. The first way is to register them using the web.xml deployment descriptor, as demonstrated in Recipe 1-2. The second way to register them is to use the @WebServlet annotation. The Servlet 3.0 API introduced the @WebServlet annotation, which provides an easier technique to use for mapping a servlet to a URL. The @WebServlet annotation is placed before the declaration of a class, and it accepts the elements listed in Table 1-2. Table 1-2.  @WebServlet Annotation Elements Element Description description Description of the servlet displayName The display name of the servlet initParams Accepts list of @WebInitParam annotations largeIcon The large icon of the servlet loadOnStartup Load on start-up order of the servlet name Servlet name smallIcon The small icon of the servlet urlPatterns URL patterns that invoke the servlet Chapter 1 ■ Introduction to Servlets 12 In the solution to this recipe, the @WebServlet annotation maps the servlet class named SimpleServletNoDescriptor to the URL pattern of /SimpleServletNoDescriptor, and it also names the servlet SimpleServletNoDescriptor.   @WebServlet(name="SimpleServletNoDescriptor", urlPatterns={"/SimpleServletNoDescriptor"})   The new @WebServlet can be used rather than altering the web.xml file to register each servlet in an application. This provides ease of development and manageability. However, in some cases, it may make sense to continue using the deployment descriptor for servlet registration, such as if you do not want to recompile sources when a URL pattern changes. If you look at the web.xml listing in Recipe 1-2, you can see the following lines of XML, which map the servlet to a given URL and provide a name for the servlet. These lines of XML perform essentially the same function as the @WebServlet annotation in this recipe.   SimpleServletNoDescriptor org.javaeerecipes.chapter01.recipe01_04.SimpleServletNoDescriptor SimpleServletNoDescriptor /SimpleServletNoDescriptor   1-5. Displaying Dynamic Content with a Servlet Problem You want to display some content to a web page that may change depending upon server-side activity or user input. Solution Define a field within your servlet to contain the dynamic content that is to be displayed. Post the dynamic content on the page by appending the field containing it using the PrintWriter println method. The following example servlet declares a Date field and updates it with the current Date each time the page is loaded:   package org.javaeerecipes.chapter01.recipe01_05;   import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   /** * Recipe 1-5: Displaying Dynamic Content with a Servlet * * @author juneau */ Chapter 1 ■ Introduction to Servlets 13 @WebServlet(name = "CurrentDateAndTime", urlPatterns = {"/CurrentDateAndTime"}) public class CurrentDateAndTime extends HttpServlet {   Date currDateAndTime;   /** * Processes requests for both HTTP * GET and * POST methods. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { out.println(""); out.println(""); out.println("Servlet CurrentDateAndTime"); out.println(""); out.println(""); out.println("

Servlet CurrentDateAndTime at " + request.getContextPath() + "

"); out.println("
"); synchronized(currDateAndTime){ currDateAndTime = new Date(); out.println("The current date and time is: " + currDateAndTime); } out.println(""); out.println(""); } finally { out.close(); } }   /** * Handles the HTTP * GET method. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); }   ChaptER 1 ■ INtROdUCtION tO SERvLEtS 14 /** * Handles the HTTP * POST method. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } } Note  Servlets are mutithreaded, and many client requests may be using a servlet concurrently. When a field is declared as a Servlet class member (not within a method) as you have done with currDateAndTime, you have to assure that only one client request can manipulate the field at any instance. You do this by synchronizing around the use of the field, as shown in the processRequest() method. You synchronize around the smallest block of code you can manage in order to minimize latency. synchronized( currDateAndTime ) { currDateAndTime = new Date(); out.println("The current date and time is: " + currDateAndTime); } The resulting output from this servlet will be the current date and time. How It Works One of the reasons why Java servlets are so useful is because they allow dynamic content to be displayed on a web page. The content can be taken from the server itself, a database, another web site, or many other web-accessible resources. Servlets are not static web pages; they are dynamic, and that is arguably their biggest strength. In the solution to this recipe, a servlet is used to display the current time and date on the server. When the servlet is processed, the doGet method is called, which subsequently makes a call to the processRequest method, passing the request and response objects. Therefore, the processRequest method is where the bulk of the work occurs. The processRequest method creates a PrintWriter by calling the response.getWriter method, and the PrintWriter is used to display content on the resulting web page. Next, the current date and time are obtained from the server by creating a new Date and assigning it to the currDateAndTime field. Lastly, the processRequest method sends the web content through the out.println method, and the contents of the currDateAndTime field are concatenated to a String and sent to out.println as well. Each time the servlet is processed, it will display the current date and time at the time in which the servlet is invoked because a new Date is created with each request. This example just scratches the surface of what is possible with a Java servlet. Although displaying the current date and time is trivial, you could alter that logic to display the contents of any field contained within the servlet. Whether it be an int field that displays a calculation that was performed by the servlet container or a String field containing some information, the possibilities are endless. Chapter 1 ■ Introduction to Servlets 15 1-6. Handling Requests and Responses Problem You want to create a web form that accepts user input and supply a response based upon the input that has been received. Solution Create a standard HTML-based web form, and when the submit button is clicked, invoke a servlet to process the end-user input and post a response. To examine this technique, you will see two different pieces of code. The following code is HTML that is used to generate the input form. This code exists within the file recipe01_06.html. Please browse to /SimpleServlet/recipe01_06.html to execute the example. Pay particular attention to the
and tags. You will see that the form’s action parameter lists a servlet name, MathServlet.   Simple Math Servlet

This is a simple Math Servlet





  Next, take a look at the following code for a servlet named MathServlet. This is the Java code that receives the input from the HTML code listed earlier, processes it accordingly, and posts a response.   package org.javaeerecipes.chapter01.recipe01_06;   import java.io.IOException; import java.io.PrintWriter; import java.util.Date;   import javax.servlet.*; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*;   /** * Recipe 1-6: Handling Requests and Responses */ // Uncomment the following line to run example stand-alone //@WebServlet(name="SessionServlet", urlPatterns={"/MathServlet"})   Chapter 1 ■ Introduction to Servlets 16 // The following will allow the example to run within the context of the JavaEERecipes example // enterprise application (JavaEERecipes.war distro or Netbeans Project @WebServlet(name = "MathServlet", urlPatterns = {"/chapter01/MathServlet"})public class MathServlet extends HttpServlet {   public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {   res.setContentType("text/html");   // Store the input parameter values into Strings String numA = req.getParameter("numa"); String numB = req.getParameter("numb");   PrintWriter out = res.getWriter(); out.println(""); out.println("Test Math Servlet"); out.println("\t"); out.println(""); out.println("");   try { int solution = Integer.valueOf(numA) + Integer.valueOf(numB);   /* * Display some response to the user */ out.println("

Solution: " + numA + " + " + numB + " = " + solution + "

");   } catch (java.lang.NumberFormatException ex) { // Display error if an exception is raised out.println("

Please use numbers only. . .try again.

"); } out.println("

"); out.println("Add Two More Numbers"); out.println("");   out.close(); } }   4 Chapter 1 ■ Introduction to Servlets 17 Note■■ to run the example, copy the previous HTML code into an HTML file within the web root of your JavaEERecipes application named recipe1_6.html, and then enter the following address into your browser: http://localhost:8080/ JavaEERecipes/recipe1_6.html. This assumes you are using default port numbers for your application server installation. If using the NetBeans project that was packaged with the sources, you do not need to worry about copying the code as everything is pre-configured. How It Works Servlets make it easy to create web applications that adhere to a request and response life cycle. They have the ability to provide HTTP responses and also process business logic within the same body of code. The ability to process business logic makes servlets much more powerful than standard HTML code. The solution to this recipe demonstrates a standard servlet structure for processing requests and sending responses. An HTML web form contains parameters that are sent to a servlet. The servlet then processes those parameters in some fashion and publishes a response that can be seen by the client. In the case of an HttpServlet object, the client is a web browser, and the response is a web page. Values can be obtained from an HTML form by using HTML tags embedded within an HTML
. In the solution to this recipe, two values are accepted as input, and they are referenced by their id attributes as numa and numb. There are two more tags within the form; one of them is used to submit the values to the form action, and the other is used to reset the form fields to blank. The form action is the name of the servlet that the form values will be passed to as parameters. In this case, the action is set to MathServlet. The tag also accepts a form-processing method, either GET or POST. In the example, the POST method is used because form data is being sent to the action; in this case, data is being sent to MathServlet. You could, of course, create an HTML form as detailed as you would like and then have that data sent to any servlet in the same manner. This example is relatively basic; it serves to give you an understanding of how the processing is performed. The action attribute states that the MathServlet should be used to process the values that are contained within the form. The MathServlet name is mapped back to the MathServlet class via the web.xml deployment descriptor or the @WebServlet annotation. Looking at the MathServlet code, you can see that a doPost method is implemented to handle the processing of the POST form values. The doPost method accepts HttpServletRequest and HttpServletResponse objects as arguments. The values contained with the HTML form are embodied within the HttpServletRequest object. To obtain those values, call the request object’s getParameter method, passing the id of the input parameter you want to obtain. In the solution to this recipe, those values are obtained and stored within local String fields.   String numA = req.getParameter("numa"); String numB = req.getParameter("numb");   Once the values are obtained, they can be processed as needed. In this case, those String values are converted into int values, and then they are added together to generate a sum and stored into an int field. That field is then presented as a response on a resulting web page.   int solution = Integer.valueOf(numA) + Integer.valueOf(numB);   As mentioned, the HTML form could be much more complex, containing any number of fields. Likewise, the servlet could perform more complex processing of those field values. This example is merely the tip of the iceberg, and the possibilities are without bounds. Servlet-based web frameworks such as Java Server Pages and Java Server Faces hide many of the complexities of passing form values to a servlet and processing a response. However, the same basic framework is used behind the scenes. Chapter 1 ■ Introduction to Servlets 18 1-7. Listening for Servlet Container Events Problem You want to have the ability to listen for application start-up and shutdown events. Solution Create a servlet context event listener to alert when the application has started up or when it has been shut down. The following solution demonstrates the code for a context listener, which will log application start-up and shutdown events and send e-mail alerting of such events:   package org.javaeerecipes.chapter01.recipe01_07;   import java.util.Properties; import javax.mail.Message; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import javax.servlet.ServletContextListener; import javax.servlet.ServletContextEvent; import javax.servlet.annotation.WebListener;   @WebListener public class StartupShutdownListener implements ServletContextListener {   public void contextInitialized(ServletContextEvent event) { System.out.println("Servlet startup. . ."); System.out.println(event.getServletContext().getServerInfo()); System.out.println(System.currentTimeMillis()); sendEmail("Servlet context has initialized"); }   public void contextDestroyed(ServletContextEvent event) { System.out.println("Servlet shutdown. . ."); System.out.println(event.getServletContext().getServerInfo()); System.out.println(System.currentTimeMillis()); // See error in server.log file if mail is unsuccessful sendEmail("Servlet context has been destroyed. . ."); }   /** * This implementation uses the GMail smtp server * @param message * @return */ private boolean sendEmail(String message) { boolean result = false; String smtpHost = "smtp.gmail.com"; String smtpUsername = "username"; Chapter 1 ■ Introduction to Servlets 19 String smtpPassword = "password"; String from = "fromaddress"; String to = "toaddress"; int smtpPort = 587; System.out.println("sending email. . ."); try { // Send email here   //Set the host smtp address Properties props = new Properties(); props.put("mail.smtp.host", smtpHost); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.starttls.enable", "true");   // create some properties and get the default Session Session session = Session.getInstance(props);   // create a message Message msg = new MimeMessage(session);   // set the from and to address InternetAddress addressFrom = new InternetAddress(from); msg.setFrom(addressFrom); InternetAddress[] address = new InternetAddress[1]; address[0] = new InternetAddress(to); msg.setRecipients(Message.RecipientType.TO, address); msg.setSubject("Servlet container shutting down"); // Append Footer msg.setContent(message, "text/plain"); Transport transport = session.getTransport("smtp"); transport.connect(smtpHost, smtpPort, smtpUsername, smtpPassword);   Transport.send(msg);   result = true; } catch (javax.mail.MessagingException ex) { ex.printStackTrace(); result = false; } return result; } }  Note■■ to run this example, you may need additional external JARs in your CLASSPATH. Specifically, make sure you have mail.jar and javaee.jar. Chapter 1 ■ Introduction to Servlets 20 How It Works Sometimes it is useful to know when certain events occur within the application server container. This concept can be useful under many different circumstances, but most often it would likely be used for initializing an application upon start-up or cleaning up after an application upon shutdown. A servlet listener can be registered with an application to indicate when it has been started up or shut down. Therefore, by listening for such events, the servlet has the opportunity to perform some actions when they occur. To create a listener that performs actions based upon a container event, you must develop a class that implements the ServletContextListener interface. The methods that need to be implemented are contextInitialized and contextDestroyed. Both of the methods accept a ServletContextEvent as an argument, and they are automatically called each time the servlet container is initialized or shut down, respectively. To register the listener with the container, you can use one of the following techniques: Utilize the • @WebListener annotation, as demonstrated by the solution to this recipe. Register the listener within the • web.xml application deployment descriptor. Use the • addListener methods defined on ServletContext. For example, to register this listener within web.xml, you would need to add the following lines of XML:   org.javaeerecipes.chapter01.recipe01_07.StartupShutdownListener   Neither way is better than the other. The only time that listener registration within the application deployment descriptor (web.xml) would be more helpful is if you had the need to disable the listener in some cases. On the other hand, to disable a listener when it is registered using @WebListener, you must remove the annotation and recompile the code. Altering the web deployment descriptor does not require any code to be recompiled. There are many different listener types, and the interface that the class implements is what determines the listener type. For instance, in the solution to this recipe, the class implements the ServletContextListener interface. Doing so creates a listener for servlet context events. If, however, the class implements HttpSessionListener, it would be a listener for HTTP session events. The following is a complete listing of listener interfaces:   javax.servlet.ServletRequestListener javax.servlet.ServletRequestAttrbiteListener javax.servlet.ServletContextListener javax.servlet.ServletContextAttributeListener javax.servlet.HttpSessionListener javax.servlet.HttpSessionAttributeListener   It is also possible to create a listener that implements multiple listener interfaces. To learn more about listening for different situations such as attribute changes, please see Recipe 1-10. t Chapter 1 ■ Introduction to Servlets 21 1-8. Setting Initialization Parameters Problem A servlet you are writing requires the ability to accept one or more parameters to be set upon initialization. Solution #1 Set the servlet initialization parameters using the @WebInitParam annotation. The following code sets an initialization parameter that is equal to a String value:   package org.javaeerecipes.chapter01.recipe01_08;   import java.io.IOException; import java.io.PrintWriter;   import javax.servlet.*; import javax.servlet.annotation.WebInitParam; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*;   @WebServlet(name="SimpleServletCtx1", urlPatterns={"/SimpleServletCtx1"}, initParams={ @WebInitParam(name="name", value="Duke") }) public class SimpleServletCtx1 extends HttpServlet {   @Override public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {   res.setContentType("text/html");   PrintWriter out = res.getWriter();   /* Display some response to the user */   out.println(""); out.println("Simple Servlet Context Example"); out.println("\t"); out.println(""); out.println("");   out.println("

This is a simple servlet to demonstrate context! Hello " + getServletConfig().getInitParameter("name") + "

");   out.println(""); out.close(); } }   Chapter 1 ■ Introduction to Servlets 22 To execute the example using the sources for this book, load the following URL into your web browser: http://localhost:8080/JavaEERecipes/SimpleServletCtx1. The resulting web page will display the following text:   This is a simple servlet to demonstrate context! Hello Duke  Solution #2 Place the init parameters inside the web.xml deployment descriptor file. The following lines are excerpted from the web.xml deployment descriptor for the SimpleServlet application. They include the initialization parameter names and values.   SimpleServletCtx1 org.javaeerecipes.chapter01.recipe01_08.SimpleServletCtx1 name Duke . . . . . .   How It Works Oftentimes there is a requirement to set initialization parameters for a servlet in order to initialize certain values. Servlets can accept any number of initialization parameters, and there are a couple of ways in which they can be set. The first solution is to annotate the servlet class with the @WebInitParam annotation, as demonstrated in Solution #1, and the second way to set an initialization parameter is to declare the parameter within the web.xml deployment descriptor, as demonstrated in Solution #2. Either way will work; however, the solution using @WebInitParam is based upon the newer Java Servlet 3.0 API. Therefore, Solution #1 is the more contemporary approach, but Solution #2 remains valid for following an older model or using an older Java servlet release. To use the @WebInitParam annotation, it must be embedded within the @WebServlet annotation. Therefore, the servlet must be registered with the web application via the @WebServlet annotation rather than within the web.xml file. For more information on registering a servlet via the @WebServlet annotation, see Recipe 1-4. The @WebInitParam annotation accepts a name-value pair as an initialization parameter. In the solution to this recipe, the parameter name is name, and the value is Duke.   @WebInitParam(name="name", value="Duke")   Once set, the parameter can be used within code by calling getServletConfig(). getInitializationParameter() and passing the name of the parameter, as shown in the following line of code:   out.println("

This is a simple servlet to demonstrate context! Hello " + getServletConfig().getInitParameter("name") + "

");   The annotations have the benefit of providing ease of development, and they also make it easier to maintain servlets as a single package rather than jumping back and forth between the servlet and the deployment descriptor. Chapter 1 ■ Introduction to Servlets 23 However, those benefits come at the cost of compilation because in order to change the value of an initialization parameter using the @WebInitParam annotation, you must recompile the code. Such is not the case when using the web.xml deployment descriptor. It is best to evaluate your application circumstances before committing to a standard for naming initialization parameters. 1-9. Filtering Web Requests Problem You want to invoke certain processing if a specified URL is used to access your application. For instance, if a specific URL were used to access your application, you would want to log the user’s IP address. Solution Create a servlet filter that will be processed when the specified URL format is used to access the application. In this example, the filter will be executed when a URL conforming to the format of /* is used. This format pertains to any URL in the application. Therefore, any page will cause the servlet to be invoked.   package org.javaeerecipes.chapter01.recipe01_09;   import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.*;   /** * Recipe 1-9 This filter obtains the IP address of the remote host and logs * it. * * @author juneau */ @WebFilter("/*") public class LoggingFilter implements Filter {   private FilterConfig filterConf = null;   public void init(FilterConfig filterConf) { this.filterConf = filterConf; }   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { String userAddy = request.getRemoteHost(); filterConf.getServletContext().log("Vistor User IP: " + userAddy); chain.doFilter(request, response); }   ChaptER 1 ■ INtROdUCtION tO SERvLEtS 24 @Override public void destroy() { throw new UnsupportedOperationException("Not supported yet."); } } The filter could contain any processing; the important thing to note is that this servlet is processed when a specified URL is used to access the application. Note Tto invoke the filter, load a URL for the application with which the filter is associated. For the purposes of this example, load the following URL (for the previous recipe) to see the filter add text to the server log: http://localhost:8080/JavaEERecipes/SimpleServletCtx1. How It Works Web filters are useful for preprocessing requests and invoking certain functionality when a given URL is visited. Rather than invoking a servlet that exists at a given URL directly, any filter that contains the same URL pattern will be invoked prior to the servlet. This can be helpful in many situations, perhaps the most useful for performing logging, authentication, or other services that occur in the background without user interaction. Filters must implement the javax.servlet.Filter interface. Methods contained within this interface include init, destroy, and doFilter. The init and destroy methods are invoked by the container. The doFilter method is used to implement tasks for the filter class. As you can see from the solution to this recipe, the filter class has access to the ServletRequest and ServletResponse objects. This means the request can be captured, and information can be obtained from it. This also means the request can be modified if need be. For example, including the user name in the request after an authentication filter has been used. If you want to chain filters or if more than one filter exists for a given URL pattern, they will be invoked in the order in which they are configured in the web.xml deployment descriptor. It is best to manually configure the filters if you are using more than one per URL pattern rather than using the @WebFilter annotation. To manually configure the web.xml file to include a filter, use the and XML elements along with their associated child element tags. The following excerpt from a web.xml configuration file shows how the filter that has been created for this recipe may be manually configured within the web.xml file: LoggingFilter LoggingFilter LogingFilter /* Of course, the @WebFilter annotation takes care of the configuration for you, so in this case the manual configuration is not required. Note Aas of Servlet 3.1 apI, if a filter invokes the next entity in the chain, each of the filter service methods must run in the same thread as all filters that apply to the servlet. Chapter 1 ■ Introduction to Servlets 25 1-10. Listening for Attribute Changes Problem You want to have the ability to do something within a servlet when a servlet attribute is added, removed, or updated. Solution Generate an attribute listener servlet to listen for such events as attributes being added, removed, or modified. The following class demonstrates this technique by implementing HttpSessionAttributeListener and listening for attributes that are added, removed, or replaced within the HTTP session:   package org.javaeerecipes.chapter01.recipe01_10;   import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingEvent;   /** * Recipe 1-10: Attribute Listener */ @WebListener public final class AttributeListener implements ServletContextListener, HttpSessionAttributeListener {   private ServletContext context = null;   public void attributeAdded(HttpSessionBindingEvent se) { HttpSession session = se.getSession(); String id = session.getId(); String name = se.getName(); String value = (String) se.getValue(); String message = new StringBuffer("New attribute has been added to session: \n"). append("Attribute Name: ").append(name).append("\n").append("Attribute Value:").append(value). toString(); log(message); }   public void attributeRemoved(HttpSessionBindingEvent se) { HttpSession session = se.getSession(); String id = session.getId(); String name = se.getName(); if (name == null) { name = "Unknown"; } String value = (String) se.getValue(); String message = new StringBuffer("Attribute has been removed: \n") Chapter 1 ■ Introduction to Servlets 26 .append("Attribute Name: ").append(name).append("\n").append("Attribute Value:") .append(value).toString(); log(message); }   public void attributeReplaced(HttpSessionBindingEvent se) { String name = se.getName(); if (name == null) { name = "Unknown"; } String value = (String) se.getValue(); String message = new StringBuffer("Attribute has been replaced: \n ").append(name). toString(); log(message); }   private void log(String message) { if (context != null) { context.log("SessionListener: " + message); } else { System.out.println("SessionListener: " + message); } }   @Override public void contextInitialized(ServletContextEvent event) { this.context = event.getServletContext(); log("contextInitialized()"); }   @Override public void contextDestroyed(ServletContextEvent event) { // Do something } }   Messages will be displayed within the server log file indicating when attributes have been added, removed, or replaced. How It Works In some situations, it can be useful to know when an attribute has been set or what an attribute value has been set to. The solution to this recipe demonstrates how to create an attribute listener in order to determine this information. To create a servlet listener, you must implement one or more of the servlet listener interfaces. To listen for HTTP session attribute changes, implement HttpSessionAttributeListener. In doing so, the listener will implement the attributeAdded, attributeRemoved, and attributeReplaced methods. Each of these methods accepts HttpSessionBindingEvent as an argument, and their implementation defines what will occur when an HTTP session attribute is added, removed, or changed, respectively. In the solution to this recipe, you can see that each of the three methods listed in the previous paragraph contains a similar implementation. Within each method, the HttpSessionBindingEvent is interrogated and broken down into String values, which represent the ID, name, and value of the attribute that caused the listener to react. For instance, Chapter 1 ■ Introduction to Servlets 27 in the attributeAdded method, the session is obtained from HttpSessionBindingEvent, and then the session ID is retrieved from that via the use of getSession. The attribute information can be obtained directly from the HttpSessionBindingEvent using the getId and getName methods, as shown in the following lines of code:   HttpSession session = se.getSession(); String id = session.getId(); String name = se.getName(); String value = (String) se.getValue();   After these values are obtained, the application can do whatever it needs to do with them. In this recipe, the attribute ID, name, and session ID are simply logged and printed.   String message = new StringBuffer("New attribute has been added to session: \n") .append("Attribute Name: ").append(name).append("\n") .append("Attribute Value:").append(value).toString(); log(message);   The body of the attributeReplaced and attributeRemoved methods contain similar functionality. In the end, the same routine is used within each to obtain the attribute name and value, and then something is done with those values. A few different options can be used to register the listener with the container. The @WebListener annotation is the easiest way to do so, and the only downfall to using it is that you will need to recompile code in order to remove the listener annotation if you ever need to do so. The listener can be registered within the web deployment descriptor, or it can be registered using one of the addListener methods contained in ServletContext. Although the example in the recipe does not perform any life-changing events, it does demonstrate how to create and use an attribute listener. In the real world, such a listener could become handy if an application needed to capture the user name of everyone who logs in or needed to send an e-mail whenever a specified attribute is set. 1-11. Applying a Listener to a Session Problem You want to listen for sessions to be created and destroyed so that you can count how many active sessions your application currently contains as well as perform some initialization for each session. Solution Create a session listener, and implement the sessionCreated and sessionDestroyed methods accordingly. In the following example, a servlet is used to keep track of active sessions. Each time someone works with the application, a counter has one added to it. Likewise, each time a person leaves the application, then the counter goes down by one.   package org.javaeerecipes.chapter01.recipe01_11;   import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener;   Chapter 1 ■ Introduction to Servlets 28 /** * Recipe 1-11: Applying a Session Listener * * @author juneau */ @WebListener public class SessionListener implements HttpSessionListener {   private int numberOfSessions;   public SessionListener() { numberOfSessions = 0; }   public int getNumberOfSessions() { return numberOfSessions; }   @Override public void sessionCreated(HttpSessionEvent arg) { HttpSession session = arg.getSession(); session.setMaxInactiveInterval(60); session.setAttribute("testAttr", "testVal"); synchronized (this) { numberOfSessions++; } System.out.println("Session created, current count: " + numberOfSessions); }   @Override public void sessionDestroyed(HttpSessionEvent arg) { HttpSession session = arg.getSession(); synchronized (this) { numberOfSessions--; } System.out.println("Session destroyed, current count: " + numberOfSessions); System.out.println("The attribute value: " + session.getAttribute(("testAttr"))); } }   Each time a new visitor visits the application, a new session is started, and testAttr is set. When the session times out, then it will be destroyed, and any attributes that have been set for the session will be removed. How It Works A meaningful way to track web application users is to place values in their HttpSession object. Using a Java servlet, session attributes can be set, which will exist for the life of the HttpSession. Once the session is invalidated, the attributes will be removed. To set up a session listener, create a Java servlet, annotate it with the @WebListener annotation, and implement javax.servlet.http.HttpSessionListener. Doing so will force the implementation of both the sessionCreated and sessionDestroyed methods, which is where the session magic occurs. Chapter 1 ■ Introduction to Servlets 29 In the example to this recipe, the sessionCreated method first obtains a handle on the current HttpSession object by calling the HttpSessionEvent object’s getSession method. The handle is assigned to an HttpSession variable named session. Now that you have that variable initialized with the session object, it can be used to set the time of life and place attributes that will live and die with the session’s life. The first session configuration performed in the example is to set the maximum inactive life to 60 (seconds), after which time the servlet container will invalidate the session. Next an attribute named testAttr is set in the session and given a value of testVal.   HttpSession session = arg.getSession(); session.setMaxInactiveInterval(60); session.setAttribute("testAttr", "testVal");   A field within the servlet named numberOfSessions is declared, and it is incremented each time a new session is started. Following the session.setAttribute() call, the counter is incremented within a synchronized statement. Finally, a message is printed to the server log indicating that a new session was created and providing the total active session count. Note■■ placing the increment within the synchronized statement helps avoid concurrency issues with the field. For more information on Java synchronization and concurrency, please see the online documentation at http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html. The sessionDestroyed method is called on a session once the maximum number of inactive seconds has passed. In this example, the method will be called after 60 seconds of inactivity. Within the sessionDestroyed method, another synchronization statement decrements the numberOfSessions field value by one, and then a couple of lines are printed to the server log indicating that a session has been destroyed and providing the new total number of active sessions. Session listeners can be used to set cookies and perform other useful tactics to help manage a user’s experience. They are easy to use and very powerful. 1-12. Managing Session Attributes Problem You want to maintain some information regarding an individual session on a per-session basis when a user visits your site. Solution Make use of session attributes to retain session-based information. To do so, use the HttpServletRequest object to obtain access to the session, and then use the getAttribute() and setAttribute() methods accordingly. In the following scenario, an HTML page is used to capture a user’s e-mail address, and then the e-mail address is placed into a session attribute. The attribute is then used by Java servlets across different pages of the application in order to maintain state. The following code demonstrates what the HTML form (recipe01_12.html) may look like in this scenario:   Chapter 1 ■ Introduction to Servlets 30

Provide an email address to use with this transaction



  Next, the Java servlet named SessionServlet using a URL pattern of /SessionServlet is initiated when the form is submitted. Any form input values are passed to SessionServlet and processed accordingly.   package org.javaeerecipes.chapter01.recipe01_12;   import java.io.*; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*;   // Uncomment the following line to run example stand-alone //@WebServlet(name="SessionServlet", urlPatterns={"/SessionServlet"})   // The following will allow the example to run within the context of the JavaEERecipes example // enterprise application (JavaEERecipes.war distro or Netbeans Project @WebServlet(name="SessionServlet", urlPatterns={"/chapter01/SessionServlet"}) public class SessionServlet extends HttpServlet { public void doPost (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {   // Obtain he Session object   HttpSession session = req.getSession(true);   // Set up a session attribute   String email = (String) session.getAttribute ("session.email"); if (email == null) { email = req.getParameter("email"); session.setAttribute ("session.email", email); } String sessionId = session.getId();   res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println(""); out.println("Working with sessions"); out.println(""); Chapter 1 ■ Introduction to Servlets 31 out.println("

Session Test

"); out.println ("Your email address is: " + email + "

"); out.println ("Your session id: " + sessionId); out.println(""); } }   In the end, the e-mail address that was entered within the original HTML form was captured and used throughout the different pages in the application. How It Works Since the beginning of web development, session attributes have been used to retain important information regarding a user’s session. This concept holds true when developing using Java servlets as well, and servlets make it easy to set and get the attribute values. All HttpServlet classes must implement doGet or doPost methods in order to process web application events. In doing so, these methods have access to the HttpServletRequest object as it is passed to them as an argument. An HttpSession object can be gleaned from the HttpServletRequest, and therefore, it can be used to retrieve and set attributes as needed. In the solution to this recipe, an HTTP session attribute is used to store an e-mail address. That address is then used throughout the application within different servlet classes by obtaining the session object and then retrieving the attribute value.   // Obtain the Session object HttpSession session = req.getSession(true); // Set up a session attribute String email = (String) session.getAttribute ("session.email"); if (email == null) { email = req.getParameter("email"); session.setAttribute ("session.email", email); }   Any attributes will remain in the HttpSession object as long as the session remains valid. The session ID will remain consistent when traversing between pages. You can see that the solution to this recipe obtains and prints the current session ID for reference. Using attributes in the HttpSession is a good way to pass data around to maintain a session’s state. 1-13. Downloading a File Problem You want to enable your servlet application to have the ability to download a given file. Solution Write a servlet that will accept the name and path of a chosen file and then read the file and stream it to the file requestor. The following web page can be used to select a file for the servlet to download. Although the following Chapter 1 ■ Introduction to Servlets 32 HTML (recipe 01_13.html) contains a statically typed file name, it could very well contain a dynamic list of files from a database or other source:  

Click on the link below to download the file.


Download test file
    Note■■   For the example in this recipe, you can create and edit a file in your root directory and name the file downloadTest.txt to see the servlet transfer the data to your browser client. When a user clicks the link presented on the web page from the previous HTML, the following servlet will be used to download the given file by passing the HttpServletRequest and HttpServletResponse objects to it along with the file that should be downloaded:   package org.javaeerecipes.chapter01.recipe01_13;   import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   /** * Recipe 1-13 * * @author juneau */ // Uncomment the following line to run example stand-alone //@WebServlet(name = "DownloadServlet", urlPatterns = {"/DownloadServlet"})   Chapter 1 ■ Introduction to Servlets 33 // The following will allow the example to run within the context of the JavaEERecipes example // enterprise application (JavaEERecipes.war distro or Netbeans Project @WebServlet(name = "DownloadServlet", urlPatterns = {"/chapter01/DownloadServlet"})public class DownloadServlet extends HttpServlet {   /** * Handles the HTTP * GET method. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Read parameter from form that contains the filename to download String fileToDownload = request.getParameter("filename"); // Call the download method with the given file System.err.println("Downloading file now. . ."); doDownload(request, response, fileToDownload); }    /** * Sends a file to the output stream. * * @param req The request * @param resp The response * @param original_filename The name the browser should receive. */ private void doDownload( HttpServletRequest request, HttpServletResponse response, String originalFile) throws IOException { final int BYTES = 1024; int length = 0; ServletOutputStream outStream = response.getOutputStream(); ServletContext context = getServletConfig().getServletContext();    response.setContentType( (context.getMimeType( originalFile ) != null) ? context.getMimeType( originalFile ) : "text/plain" ); response.setHeader( "Content-Disposition", "attachment; filename=\"" + originalFile + "\"" );   InputStream in = context.getResourceAsStream("/" + originalFile); byte[] bbuf = new byte[BYTES];   while ((in != null) && ((length = in.read(bbuf)) != -1)) { outStream.write(bbuf,0,length); }   outStream.flush(); outStream.close(); }   ChaptER 1 ■ INtROdUCtION tO SERvLEtS 34 /** * Returns a short description of the servlet. * * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; } } The servlet will not produce a response; it will simply download the given file to the end user when the user clicks the link to download the file. How It Works Downloading files is an essential task for almost any web application. Performing the steps that are provided by this recipe will make it easy to achieve this task. The example in this recipe demonstrates an easy case in which users can visit a web page, click a file to download, and have the file retrieved from the server and copied to their machine. The HTML is very simplistic in this example, and it lists a URL link that invokes the servlet and passes the name of the file that is to be downloaded. When the user clicks the link, the name of the file is passed to /DownloadServlet as a parameter with the name filename. When the link is clicked, the servlet doGet method is invoked. The first task that is performed in the doGet method is to read the filename parameter from the invoking web page. That information is then passed to the doDownload method along with the HttpServletRequest and HttpServletResponse objects. In the doDownload method, the ServletOutputStream is obtained from the HttpServletResponse object, and the ServletContext is obtained for later use. To download a file, the servlet must provide a response of the same type that matches that of the file to be downloaded. It must also indicate in the response header that an attachment is to be included. Therefore, the first tasks to be performed by the doDownload method involve setting up the HttpServletResponse appropriately. response.setContentType( (context.getMimeType( originalFile ) != null) ? context.getMimeType( originalFile ) : "text/plain" ); response.setHeader( "Content-Disposition", "attachment; filename=\"" + originalFile + "\"" ); The file name, in this case originalFile, is used to obtain the MIME type of the file. If the MIME type of the file is null, then text/plain will be returned. The attachment is set up in the response header as well, by appending the file name as an attachment to the Content-Disposition. Next, the doDownload method obtains a reference to the file that is to be downloaded by calling the ServletContext getResourceAsStream method and passing the name of the file. This will return an InputStream object that can be used to read the contents of the indicated file. A byte buffer is then created, which will be used to obtain chunks of data from the file when it is being read. The final real task is to read the file contents and copy them to the output stream. This is done using a while loop, which will continue to read from the InputStream until everything has been processed. Chunks of data are read in and written to the output stream using the loop. while ((in != null) && ((length = in.read(bbuf)) != -1)) { outStream.write(bbuf,0,length); } Chapter 1 ■ Introduction to Servlets 35 Lastly, the ServletOutputStream object’s flush method is called to clear the contents, and it is then closed to release resources. The magic of downloading files using a Java servlet may be a bit obfuscated by this example, however, because a static file is being used as the download source in this example. In real life, the HTML page would probably contain a list of files that are contained within a database, and then when the user selects a file to download, the servlet will process that file accordingly, even extracting the file from the database if necessary. 1-14. Dispatching Requests Problem You want to write a servlet that hands off requests to other servlets based upon the task that needs to be accomplished. Furthermore, you want the requests to be handed off without redirecting the client to another site, and therefore, the URL in the browser should not change. Solution Create a request dispatcher servlet, which will decide which task needs to be completed and then send the request to an appropriate servlet to achieve that task. The following example demonstrates this concept via an HTML form that accepts two numbers from the user and allows the user to decide what type of mathematical evaluation should be performed by the server. The servlet processes the request by first determining which type of mathematical evaluation should be performed and then dispatching the request to the appropriate servlet to perform the task. The following HTML form accepts two numbers from the user and allows them to choose which type of math to perform against the numbers:  

Request Dispatch Example

Perform a mathematical evaluation. Insert two numbers to be evaluated and then choose the type of evaluation to perform.





  Chapter 1 ■ Introduction to Servlets 36 The next piece of code is the servlet that will dispatch requests accordingly depending upon the value of the matheval field:   package org.javaeerecipes.chapter01.recipe01_14;   import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   /** * * @author juneau */ // Uncomment the following line to run example stand-alone //@WebServlet(name = "MathDispatcher", urlPatterns = {"/MathDispatcher"})   // The following will allow the example to run within the context of the JavaEERecipes example // enterprise application (JavaEERecipes.war distro or Netbeans Project @WebServlet(name = "MathDispatcher", urlPatterns = {"/chapter01/MathDispatcher"}) public class MathDispatcher extends HttpServlet {   /** * Handles the HTTP * POST method. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("In the servlet. . ."); // Store the input parameter values into Strings String eval = request.getParameter("matheval"); ServletContext sc = getServletConfig().getServletContext(); RequestDispatcher rd = null; int evaluate = 0; int add = 0; int subtract = 1; int multiply = 2; int divide = 3; if(eval.equals("add")) evaluate = add; Chapter 1 ■ Introduction to Servlets 37 if (eval.equals("subtract")) evaluate = subtract; if (eval.equals("multiply")) evaluate = multiply; if(eval.equals("divide")){ evaluate = divide; } switch(evaluate){ case(0): rd = sc.getRequestDispatcher("/AddServlet"); rd.forward(request, response); break; case(1): rd = sc.getRequestDispatcher("/SubtractServlet"); rd.forward(request, response); break; case(2): rd = sc.getRequestDispatcher("/MultiplyServlet"); rd.forward(request, response); break; case(3): rd = sc.getRequestDispatcher("/DivideServlet"); rd.forward(request, response); break; }   }    /** * Returns a short description of the servlet. * * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; } }   Next is an example of one of the servlets that the request will be dispatched to. The following is the code for the AddServlet, which will add the two numbers and return the sum to the user:   package org.javaeerecipes.chapter01.recipe01_14;   import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   /** * * @author juneau */ Chapter 1 ■ Introduction to Servlets 38 // Uncomment the following line to run example stand-alone //@WebServlet(name = "AddServlet", urlPatterns = {"/AddServlet"})   // The following will allow the example to run within the context of the JavaEERecipes example // enterprise application (JavaEERecipes.war distro or Netbeans Project @WebServlet(name = "AddServlet", urlPatterns = {"/chapter01/AddServlet"}) public class AddServlet extends HttpServlet {   /** * Processes requests for both HTTP * GET and * POST methods. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); // Store the input parameter values into Strings String numA = request.getParameter("numa"); String numB = request.getParameter("numb"); int sum = Integer.valueOf(numA) + Integer.valueOf(numB); try { out.println(""); out.println(""); out.println("The Sum of the Numbers"); out.println(""); out.println(""); out.println("

Sum: " + sum + "

"); out.println("
"); out.println("Try Again"); out.println(""); out.println(""); } finally { out.close(); } }   /** * Handles the HTTP * GET method. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ Chapter 1 ■ Introduction to Servlets 39 @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); }   /** * Handles the HTTP * POST method. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); }   /** * Returns a short description of the servlet. * * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; } }   Each of the other servlets is very similar to AddServlet, except the mathematical evaluation is different. To see a full listing of the code, please take a look at the sources for this book. How It Works Sometimes it is a good idea to hide the forwarding of requests from the end user. Other times it just makes sense to hand off a request from one servlet to another so that another type of processing can take place. These are just two examples of when it is handy to perform a request dispatch within a servlet. Forwarding a request versus dispatching a request is different because a forwarded request hands off the request on the client side, whereas a dispatched request hands off the request on the server side. The difference can be quite large since the end user has no idea of server-side dispatches, whereas the browser is redirected to a different URL when the request is forwarded on the client side. Dispatching requests is an easy task. The facilities for doing so are built right into the ServletContext, so once you obtain a reference to ServletContext, then you simply call the getRequestDispatcher method to obtain a RequestDispatcher object that can be used to dispatch the request. When calling the getRequestDispatcher method, pass a String containing the name of the servlet that you want to hand off the request to. You can actually obtain a RequestDisptacher object for any valid HTTP resource within the application by passing the appropriate URL for the resource in String format to the getRequestDispatcher method. Therefore, if you’d rather dispatch Chapter 1 ■ Introduction to Servlets 40 to a JSP or HTML page, you can do that as well. After a RequestDispatcher object has been obtained, invoke its forward method by passing the HttpServletRequest and HttpServletResponse objects to it. The forward method performs the task of handing off the request.   rd = sc.getRequestDispatcher("/AddServlet"); rd.forward(request, response);   In the case of the example in this recipe, you can dispatch requests to different servlets in order to perform a specific task. Once handed off, the servlet that has obtained the request is responsible for providing the response to the client. In this case, the servlet returns the result of the specified mathematical evaluation. 1-15. Redirecting to a Different Site Problem You need to redirect the browser to another URL when a specific URL within your application is visited. Solution Use the HttpServletResponse object’s sendRedirect() method to redirect from the servlet to another URL. In the following example, when a URL that matches the /redirect pattern is used, then the servlet will redirect the browser to another site:   import java.io.IOException; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*;   @WebServlet(name="RedirectServlet", urlPatterns={"/redirect"}) public class RedirectServlet extends HttpServlet {   @Override public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { String site = "http://www.apress.com";   res.sendRedirect(site); } }   In this example, the servlet will redirect to the www.apress.com web site. How It Works There are some cases in which a web application needs to redirect traffic to another site or URL within the same or another application. For such cases, the HttpServletResponse sendRedirect method can be of use. The sendRedirect method accepts a URL in String format and then redirects the web browser to the given URL. Given that sendRedirect accepts a String-based URL makes it easy to build dynamic URLs as well. For instance, Chapter 1 ■ Introduction to Servlets 41 some applications may redirect to a different URL based upon certain parameters that are passed from a user. Dynamic generation of a URL in such cases may look something like the following:   String redirectUrl = null; If(parameter.equals("SOME STRING") redirectUrl = "/" + urlPathA; else redirectUrl = "/" + urlPathB; res.sendRedirect(redirectUrl);   The sendRedirect() method can also come in handy for creating the control for web menus and other page items that can send web traffic to different locations. Note■■ this simple redirect, as opposed to servlet chaining, does not pass the HttpRequest object along to the target address. 1-16. Securely Maintaining State Within the Browser Problem You have the requirement to save a user’s state within the browser for your application. Solution Use “HTTP only” browser cookies to save the state. In the following example, one servlet is used to place some session information into a cookie in the browser. Another servlet is then called, which reads the cookie information and displays it to the user. The following servlet demonstrates how to store a cookie in the browser using a Java servlet:   package org.javaeerecipes.chapter01.recipe01_16;   import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   /** * Recipe 1-16: Securing State within the Browser * @author juneau */ @WebServlet(name = "SetCookieServlet", urlPatterns = {"/SetCookieServlet"}) public class SetCookieServlet extends HttpServlet {    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); Chapter 1 ■ Introduction to Servlets 42 PrintWriter out = response.getWriter(); Cookie cookie = new Cookie("sessionId","12345"); cookie.setHttpOnly(true); cookie.setMaxAge(-30); response.addCookie(cookie); try { out.println(""); out.println(""); out.println("SetCookieServlet"); out.println(""); out.println(""); out.println("

Servlet SetCookieServlet is setting a cookie into the browser

"); out.println("

"); out.println("Display the cookie contents."); out.println(""); out.println(""); } finally { out.close(); } }   @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); }    @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); }   }   The next code listing demonstrates a servlet that reads the cookies in the browser and prints out the contents:   package org.javaeerecipes.chapter01.recipe01_16;   import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   /** * Recipe 1-16: Securely Maintaining State within the Browser * @author juneau */ Chapter 1 ■ Introduction to Servlets 43 @WebServlet(name = "DisplayCookieServlet", urlPatterns = {"/DisplayCookieServlet"}) public class DisplayCookieServlet extends HttpServlet {   protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); Cookie[] cookies = request.getCookies();   try { out.println(""); out.println(""); out.println("Display Cookies"); out.println(""); out.println(""); for(Cookie cookie:cookies){ out.println("

"); out.println("Cookie Name: " + cookie.getName()); out.println("
"); out.println("Value: " + cookie.getValue()); out.println("

"); } out.println(""); out.println(""); } finally { out.close(); } }   @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); }   @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); }   }  How It Works Using cookies to store data within the browser is a technique that has been in practice for years. Since Servlet 3.0 API, the ability to mark a cookie as HTTP only has become available. This allows the cookie to be safeguarded against client-side scripting attacks, making the cookie more secure. Any standard servlet can create a cookie and place it into the current session. Similarly, any servlet that is contained within the same session can read or update a session’s cookies values. In the example for this recipe, two servlets are used to demonstrate how cookies work. The first servlet ChaptER 1 ■ INtROdUCtION tO SERvLEtS 44 that is listed is responsible for creating a new cookie and setting it into the browser session. The second servlet is responsible for displaying the contents of the cookie to the user. To create a cookie, simply instantiate a new javax.servlet.http.Cookie object and assign a name and value to it. Passing both the name and value into the Cookie constructor at the time of instantiation can assign a name and value, or it can be done by passing values to the cookie’s setName and setValue methods. Once the cookie has been instantiated, properties can be set that will help to configure the cookie. In the example to this recipe, the cookie’s setMaxAge and setHttpOnly methods are called, setting the time of life for the cookie and ensuring that it will be guarded against client-side scripting. For a complete listing of cookie properties, please refer to Table 1-3. Finally, the cookie is placed into the response by passing it to the response object’s addCookie method. Cookie cookie = new Cookie("sessionId","12345"); cookie.setHttpOnly(true); cookie.setMaxAge(-30); response.addCookie(cookie); Table 1-3. Cookie Property Methods Property Description setComment Sets a comment to describe the cookie. setDomain Specifies the domain in which the cookie belongs. setHttpOnly Marks the cookie as HTTP only. setMaxAge Sets the maximum lifetime of the cookie. A negative value indicates that the cookie will expire when the session ends. setPath Specifies a path for the cookie to which the client should return it. setSecure Indicates that the cookie should be sent only using a secure protocol. setValue Assigns a value to the cookie. setVersion Specifies the version of the cookie protocol that the cookie will comply with. The second servlet, DisplayCookieServlet, in the example is responsible for reading and displaying the session’s cookies values. When DisplayCookieServlet is invoked, its processRequest method is called, which obtains the cookies within the response object by calling response.getCookies() and setting the result to an array of Cookie objects. Cookie[] cookies = request.getCookies(); The cookie object array can now be iterated over in order to obtain each cookie and print out its contents. The servlet does so by using a for loop and printing out each cookie’s name and value. for(Cookie cookie:cookies){ out.println("

"); out.println("Cookie Name: " + cookie.getName()); out.println("
"); out.println("Value: " + cookie.getValue()); out.println("

"); } Chapter 1 ■ Introduction to Servlets 45 1-17. Finalizing Servlet Tasks Problem There are some resources you want to have your servlet clean up once the servlet is no longer in use. Solution The solution to the problem is twofold. First, provide code for performing any cleanup within the servlet destroy method. Second, in the case that there are potentially long-running methods, code them so that you will become aware of a shutdown and, if necessary, halt and return so that the servlet can shut down cleanly. The following code excerpt is a small example of a destroy method. In this code, it is being used to initialize local variables and is setting the beingDestroyed boolean value to indicate that the servlet is shutting down.   . . . /** * Used to finalize the servlet */ public void destroy() { // Tell the servlet it is shutting down setBeingDestroyed(true); // Perform any cleanup thisString = null;   } . . .   The code within the destroy method may successfully achieve a full cleanup of the servlet, but in the case where there may be a long-running task, then it must be notified of a shutdown. The following excerpt is a block of code that signifies a long-running task. The task should stop processing once the shutdown is indicated by the beingDestroyed value becoming true.   for (int x = 0; (x <= 100000 && !isBeingDestroyed()); x++) { doSomething(); }  How It Works The finalization of a servlet can be very important, especially if the servlet is using some resources that may lead to a memory leak, making use of a reusable resource such as a database connection or in order to persist some values for another session. In such cases, it is a good idea to perform cleanup within the servlet destroy method. Every servlet contains a destroy method (which may be implemented to overload default behavior) that is initiated once the servlet container determines that a servlet should be taken out of service. The destroy method is called once all of a servlet’s service methods have stopped running. However, if there is a long-running service method, then a server grace period can be set that would cause any running service to be shut down when the grace period is reached. As mentioned earlier, the destroy method is the perfect place to clean up resources. However, the destroy method is also a good place to help clean up after long-running services. Cleanup can be done by setting a servlet-specific local variable to indicate that the servlet is being destroyed and by having the long-running service check the state of that variable periodically. If the variable indicates that the destroy method has been called, then it should stop executing. Chapter 1 ■ Introduction to Servlets 46 1-18. Reading and Writing with Nonblocking I/O Problem You want to read and write I/O in an asynchronous, nonblocking manner. Solution Use the Non-Blocking I/O API that is part of the Servlet 3.1 release. To use the new technology, implement the new ReadListener interface when performing nonblocking reads, and implement the WriteListener interface for performing nonblocking writes. The implementation class can then be registered to a ServletInputStream or ServletOutputStream so that reads or writes can be performed when the listener finds that servlet content can be read or written without blocking. The following sources are those of a ReadListener implementation that reside in the source file org.javaeerecipes.chapter01.recipe01_18.AcmeReadListenerImpl.java, and they demonstrate how to implement the ReadListener:   package org.javaeerecipes.chapter01.recipe01_18;   import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.AsyncContext; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream;   public class AcmeReadListenerImpl implements ReadListener {   private ServletInputStream is = null; private AsyncContext async = null;   public AcmeReadListenerImpl(ServletInputStream in, AsyncContext ac) { this.is = in; this.async = ac; System.out.println("read listener initialized"); }   @Override public void onDataAvailable() { System.out.println("onDataAvailable"); try { StringBuilder sb = new StringBuilder(); int len = -1; byte b[] = new byte[1024]; while (is.isReady() && (len = is.read(b)) != -1) { String data = new String(b, 0, len); System.out.println(data); } } catch (IOException ex) { Logger.getLogger(AcmeReadListenerImpl.class.getName()).log(Level.SEVERE, null, ex); } }    Chapter 1 ■ Introduction to Servlets 47   @Override public void onAllDataRead() { System.out.println("onAllDataRead"); async.complete();   }   @Override public void onError(Throwable thrwbl) { System.out.println("Error: " + thrwbl); async.complete(); }   }   Next, use the listener by registering it to a ServletInputStream (in the case of the ReadListener) or a ServletOutputStream (in the case of a WriteListener). For this example, I’ll show a servlet that utilizes the AcmeReadListenerImpl class. The sources for the following class reside within the file org.javaeerecipes.chapter01.recipe01_18.AcmeReaderExample.java:   package org.javaeerecipes.chapter01.recipe01_18;   import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.concurrent.CountDownLatch; import javax.servlet.AsyncContext; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   @WebServlet(urlPatterns = {"/AcmeReaderServlet"}, asyncSupported=true) public class AcmeReaderServlet extends HttpServlet {    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); try (PrintWriter output = response.getWriter()) { String filename = "test.txt"; ServletContext context = getServletContext();   InputStream in = context.getResourceAsStream(filename); output.println(""); output.println(""); output.println("Acme Reader"); output.println(""); Chapter 1 ■ Introduction to Servlets 48 output.println(""); output.println("

Welcome to the Acme Reader Servlet

"); output.println("

"); output.println("

Look at the server log to see data that was read asynchronously from a file

"); AsyncContext asyncCtx = request.startAsync(); ServletInputStream input = request.getInputStream(); input.setReadListener(new AcmeReadListenerImpl(input, asyncCtx));   output.println(""); output.println(""); } catch (Exception ex){ System.out.println("Exception Occurred: " + ex); } }     // Http Servlet Methods . . . . . . }   The last piece of code that we need is the servlet that invokes the AcmeReaderServlet, passing the message that needs to be processed. In this example, a file from the server is passed to the AcmeReaderServlet as input, which then is asynchronously processed via the AcmeReadListenerImpl class. The following code is taken from org.javaeerecipes.chapter01.recipe01_18.ReaderExample.java.   package org.javaeerecipes.chapter01.recipe01_18;   import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.URL; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   @WebServlet(name = "ReaderExample", urlPatterns = {"/ReaderExample"}) public class ReaderExample extends HttpServlet {   protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); Chapter 1 ■ Introduction to Servlets 49 String filename = "/WEB-INF/test.txt"; ServletContext context = getServletContext();   InputStream in = context.getResourceAsStream(filename); try (PrintWriter out = response.getWriter()) { String path = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/AcmeReaderServlet"; out.println(""); out.println(""); out.println("Intro to Java EE 7 - Servlet Reader Example"); out.println(""); out.println(""); out.println("

Servlet ReaderExample at " + request.getContextPath() + "

"); out.println("Invoking the endpoint: " + path + "
"); out.flush(); URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setChunkedStreamingMode(2); conn.setDoOutput(true); conn.connect(); if (in != null) { InputStreamReader inreader = new InputStreamReader(in); BufferedReader reader = new BufferedReader(inreader); String text = ""; out.println("Beginning Read"); try (BufferedWriter output = new BufferedWriter(new OutputStreamWriter(conn. getOutputStream()))) { out.println("got the output. . .beginning loop"); while ((text = reader.readLine()) != null) { out.println("reading text: " + text); out.flush(); output.write(text);   Thread.sleep(1000); output.write("Ending example now.."); out.flush(); } output.flush(); output.close(); } } out.println("Review the GlassFish server log for messages. . ."); out.println(""); out.println(""); } catch (InterruptedException | IOException ex) { Logger.getLogger(ReaderExample.class.getName()).log(Level.SEVERE, null, ex); } }   Chapter 1 ■ Introduction to Servlets 50 @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); }   @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); }   @Override public String getServletInfo() { return "Short description"; } }   When the servlet is visited, the asynchronous, nonblocking read of the test.txt file will occur, and its text will be displayed in the server log. How It Works Servlet technology has allowed only traditional (blocking) input/output during request processing since its inception. In the Servlet 3.1 release, the new Non-Blocking I/O API makes it possible for servlets to read or write without any blocking. This means other tasks can be performed at the same time that a read or write is occurring, without any wait. Such a solution opens up a new realm of possibilities for servlets, making them much more flexible for use along with modern technologies such as the WebSockets protocol. To implement a nonblocking I/O solution, new programming interfaces have been added to ServletInputStream and ServletOutputStream, as well as two event listeners: ReadListener and WriteListener. ReadListener and WriteListener interfaces make the servlet I/O processing occur in a nonblocking manner via callback methods that are invoked when servlet content can be read or written without blocking. Use the ServletInputStream.setReadList ener(ServletInputStream, AsyncContext) method to register a ReadListener with a ServletInputStream, and use the I/O read ServletInputStream.setWriteListener(ServletOutputStream,AsyncContext) method for registering a WriteListener. The following lines of code demonstrate how to register a ReadListener implementation with a ServletInputStream:   AsyncContext context = request.startAsync(); ServletInputStream input = request.getInputStream(); input.setReadListener(new ReadListenerImpl(input, context));  Note■■   In Servlet 3.0, AsyncContext was introduced to represent an execution context for an asynchronous operation that is initiated on a servlet request. To use the asynchronous context, a servlet should be annotated as a @WebServlet, and the asyncSupported attribute of the annotation must be set to true. The @WebFilter annotation also contains the asyncSupported attribute. Chapter 1 ■ Introduction to Servlets 51 After a listener has been registered with a ServletInputStream, the status on a nonblocking read can be checked by calling the methods ServletInputStream.isReady and ServletInputStream.isFinished. For instance, a read can begin once the ServletInputStream.isReady method returns a true, as shown here:   while (is.isReady() && (b = input.read()) != -1)) { len = is.read(b); String data = new String(b, 0, len); }   To create a ReadListener or WriteListener, three methods must be overridden: onDataAvailable, onAllDataRead, and onError. The onDataAvailable method is invoked when data is available to be read or written, onAllDataRead is invoked once all the data has been read or written, and onError is invoked if an error is encountered. The code for AcmeReadListenerImpl in the solution to this recipe demonstrates how to override these methods. The AsyncContext.complete() method is called in the onAllDataRead method to indicate that the read has been completed and to commit the response. This method is also called in the onError implementation so that the read will complete, so it is important to perform any cleanup within the body of the onError method to ensure that no resources are leaked, and so on. To implement a WriteListener, make use of the new ServletOutputStream.canWrite() method, which determines whether data can be written in a nonblocking fashion. A WriteListener implementation class must override a couple of methods: onWritePossible and onError. The onWritePossible method is invoked when a nonblocking write can occur. The write implementation should take place within the body of this method. The onError method is much the same as its ReadListener implementation counterpart, because it is invoked when an error occurs. The following lines of code demonstrate how to register a WriteListener with a ServletOutputStream:   AsyncContext context = request.startAsync(); ServletOutputStream os = response.getOutputStream(); os.setWriteListener(new WriteListenerImpl(os, context));   The WriteListener implementation class must include overriding methods for onWritePossible and onError. The following is an example for a WriteListener implementation class:   import javax.servlet.AsyncContext; import javax.servlet.ServletOutputStream; import javax.servlet.WriteListener;   public class WriteListenerImpl implements WriteListener {   ServletOutputStream os; AsyncContext context;   public WriteListenerImpl(ServletOutputStream out, AsyncContext ctx){ this.os = out; this.context = ctx; System.out.println("Write Listener Initialized"); }   @Override public void onWritePossible() { System.out.println("Now possible to write. . ."); // Write implementation goes here. . . }   Chapter 1 ■ Introduction to Servlets 52 @Override public void onError(Throwable thrwbl) { System.out.println("Error occurred"); context.complete(); }   }  Note■■   In most cases, the ReadListener and WriteListener implementation classes can be embedded within the calling servlet. They have been broken out into separate classes for the examples in this book for demonstration purposes. The new Non-Blocking I/O API helps bring the Servlet API into compliance with new web standards. The new API makes it possible to create web-based applications that perform well in an asynchronous fashion. 53 Chapter 2 JavaServer Pages The JavaServer Pages (JSP) web framework introduced a great productivity boost for Java web developers over the Java Servlet API. When the JSP technology was introduced in 1999, it was Sun’s answer to PHP and ASP, which provided web developers with a quick way to create dynamic web content. JSPs contain a mix of XML and HTML but can also contain embedded Java code within scripting elements known as scriptlets. Indeed, JSPs are easy to learn and allow developers to quickly create dynamic content and use their favorite HTML editor to lay out nice-looking pages. JSP was introduced several years ago and still remains one of the most important Java web technologies available. Although JSP technology has changed over the years, there are still many applications using older JSP variations in the world today. Over the years, the creation of dynamic web content has solidified, and the techniques used to develop web applications have become easier to maintain down the road. Whereas early JSP applications included a mix of Java and XML markup within the pages, today the separation of markup from business logic is increasingly important. Newer releases of the JSP technology have accounted for these changes in the web space, and the most recent releases allow developers the flexibility to develop highly dynamic content without utilizing any embedded Java code but, instead, making use of markup and custom tags within pages. This chapter will show you the ins and outs of JSP development. Starting with creating a simple JSP application, you will learn how to develop applications using JSP technology from the ground up and harness the productivity and power that the technology has to offer. The chapter also brushes upon advanced techniques such as the development of custom JSP tags and the invocation of Java functions utilizing conditional tags. Although entire books have been written on JSP, the recipes within this chapter will lay a solid foundation on which you can begin to develop applications utilizing JSP. Note■■   Utilizing a Java integrated development environment (IDE) can significantly reduce development time, especially when working with Java web technologies such as JSP. To start learning how to create a JSP application using the NetBeans IDE, please see the appendix of this book. 2-1. Creating a Simple JSP Page Problem You want to develop a web page using HTML markup that enables you to include dynamic content. ChaPTEr 2 ■ JavaSErvEr PagES 54 Solution Use JavaServer Pages to create a web page that combines standard markup with blocks of Java code that are embedded within the markup. The following JSP markup demonstrates how to include dynamic code into a page: <%-- Document : recipe02_01 Author : juneau --%> <%@page contentType="text/html" pageEncoding="UTF-8"%> JSP Page Example

Hello World!


The current date is: ${dateBean.currentDate}!

The previous JSP code uses a JavaBean to pull the current date into the page. The following Java code is the JavaBean that is used by the JSP code: package org.javaeerecipes.chapter02.recipe02_01; import java.util.Date; /** * Recipe 2-1: Creating a Simple JSP * @author juneau */ public class DateBean { private Date currentDate = new Date(); /** * @return the currentDate */ public Date getCurrentDate() { return currentDate; } Chapter 2 ■ JavaServer Pages 55 /** * @param currentDate the currentDate to set */ public void setCurrentDate(Date currentDate) { this.currentDate = currentDate; }   }   The following output would result. Of course, the page will display the current date when you run the code.   Hello World! The current date is: Fri Dec 23 10:41:07 CST 2011!  How It Works The JavaServer Pages technology makes it easy to develop web pages that can utilize both static and dynamic web content by providing a set of tags and value expressions to expose dynamic Java fields to a web page. Using the JSP technology, a page developer can access the underlying JavaBeans classes to pass content between the client and the server. In the example within this recipe, a JSP page is used to display the current date and time, which is obtained from a JavaBean class on the server. Therefore, when a user visits the JSP page in a browser, the current time and date on the server will be displayed. A JSP page should use a document extension of .jsp if it is a standard HTML-based JSP page. Other types of JSP pages contain different extensions; one of those is the JSP document type. A JSP document is an XML-based well-formed JSP page. You can learn more about JSP documents in Recipe 2-6. JSP pages can contain HTML markup, special JSP tags, page directives, JavaScript, embedded Java code, and more. This example contains the tag, as well as a value expression to display the content of a field that is contained within the JavaBean. The tag is used to include a reference to a Java class that will be referenced in the JSP page. In this case, the class that is referenced is named org.javaeerecipes.chapter02.recipe02_01.DateBean, and it will be referenced as dateBean within the page. For a full description of the tag, please reference Recipe 2-3.     Since the tag contains a reference to the DateBean Java class, the JSP page that includes the tag can make use of any public fields or methods that are contained within the class or private fields through public “getter” methods. This is demonstrated by the use of the Expression Language (EL) value expression, which is enclosed within the ${} characters. To learn more about JSP EL expressions, please see Recipe 2-4. In the example, the value of the JavaBean field named currentDate is displayed on the page. The value of the private field is retrieved automatically via the pubic “getter” method, getCurrentDate.   The current date is: ${dateBean.currentDate}!  LIFE CYCLE OF A JSP PAGE The life cycle of a JSP page is very much the same as that of a Java servlet. This is because a JSP page is translated to a servlet (the HttpJspBase JSP servlet class) behind the scenes by a special servlet. When a request is sent to a JSP page, the special servlet checks to ensure that the JSP page’s servlet is not older than the page itself. If it is, the JSP is retranslated into a servlet class and compiled. The JSP-to-servlet translation is automatic, which is one of the most productive reasons to use JSP. Chapter 2 ■ JavaServer Pages 56 When a JSP page is translated, a servlet with a name such as 0002fjspname_jsp.java is created, where jspname is the name of the JSP page. If errors result during the translation, they will be displayed when the JSP page response is displayed. Different portions of the JSP page are treated differently during the translation to a Java servlet. Template data is translated into code.• JSP scripting elements are inserted into the JSP page’s servlet class.• • elements are converted into method calls. After translation, the life cycle works similarly to the servlet life cycle: If the JSP page’s servlet does not already exist, then the container does the following:• 1. Loads the servlet class 2. Instantiates the servlet class 3. Initializes the servlet instance with a call to the jspInit method This recipe contains only beginning knowledge of what is possible with the JSP technology. To learn more regarding the technology and best practices when using JSP, please continue reading the recipes in this chapter. 2-2. Embedding Java into a JSP Page Problem You want to embed some Java code into a standard JSP web page. Solution Use JSP scripting elements to embed Java code into the page and then display Java fields. The following JSP code demonstrates how to import the Java Date class and then use it to obtain the current date without using a server-side JavaBean class:   <%-- Document : recipe02_02 Author : juneau --%>   <%@page import="java.util.Date"%> <%@page contentType="text/html" pageEncoding="UTF-8"%> <%! Date currDate = null; %> <% currDate = new Date(); %> Recipe 2-2: Embedding Java in a JSP Chapter 2 ■ JavaServer Pages 57

Hello World!



The current date and time is: <%= currDate %>     This page will display the current system date from the server that hosts the JSP application. How It Works Using scripting elements within a JSP page allows you to embed Java code directly in a web page. However, it should be noted that this is not the best approach to web development. Scripting element programming used to be one of the best ways to code web applications using JSP technology. However, when it came time to perform maintenance activities on a JSP page or to introduce new developers to a code base that used scripting elements in JSP, nightmares ensued because in order to debug a problem, the developer had to search through scripts embedded within HTML, as well as Java classes themselves. Sometimes it is still nice to have the ability to embed Java code directly into a page, even if for nothing more than testing, so that is why I show how it is done in this recipe. A better approach would be to separate the business logic from the view code, which you will see in Recipe 2-3. In the example, the current date is pulled into the JSP page via the use of the Java Date class. A new Date instance is assigned to a field that is named currDate. An import page directive is used to import the java.util.Date class into the JSP page using the following line:   <%@page import="java.util.Date"%>   The declaration of currDate is done within a declaration scripting element. Declaration scripting elements begin with the character sequence <%! and end with the character sequence %>. Excerpted from the example, the currDate field is declared in the following line of code:   <%! Date currDate = null; %>   Anything that is contained inside declarations goes directly to the jspService() method of the generated JSP servlet class, creating a global declaration for the entire servlet to make use of. Any variable or method can be declared within declarations’ character sequences. Note■■   Declarations are executed only once for the JSP page, when it is initially converted into a servlet. If any code on the JSP page changes, it will be translated to a servlet again, and the declaration will be evaluated again at that time. If you want for code to be executed each time the JSP page is loaded by the browser, do not place it in a declaration. In the example for this recipe, you can see that there are no JSP tags used to reference a server-side JavaBean class to create a new instance of the Date class, and that is because the instantiation is done right within the JSP code in between character sequences known as scriptlets, <% %>. Scriptlets basically have the same syntax as declarations, except that they do not include the exclamation point in the first character sequence. Scriptlets are used to embed any Java code that you want to have run each time the JSP is loaded, at request-processing time. At translation time, anything contained within a scriptlet is placed into a method named _jspService within the translated JSP Chapter 2 ■ JavaServer Pages 58 servlet, and that method is executed with each request on the JSP page. Scriptlets are the most common place to use embedded Java in a JSP page. Since in this example you want the current date to be displayed each time the page is loaded, the new Date class is instantiated and assigned to the currDate variable within a scriptlet.   <% currDate = new Date(); %>   Later in the JSP page, the currDate field is displayed using an expression, which is enclosed using the <%= and %> character sequences. Expressions are used to display content, and anything that is contained within an expression is automatically converted to a String when a request is processed. After the String conversion, it is displayed as output on the page.   The current date and time is: <%= currDate %>  Note■■   If the code within an expression is unable to be converted into a String, an exception will occur. While embedding Java code in a JSP page is possible to do, it is frowned upon within the Java community since the Model-View-Controller (MVC) paradigm makes coding much cleaner. To learn more about coding JSP applications without using scripting elements, please see the next recipe, Recipe 2-3. 2-3. Separating Business Logic from View Code Problem You want to separate the business logic from the code that is used to create a view within your web application. Solution Separate the business logic into a JavaBean class, and use JSP tags to incorporate the logic into the view. In the following example, a JavaBean is referenced from within a JSP page, and one of the JavaBean fields is displayed on the page. Each time the page is refreshed, the field value is updated because the page calls the underlying JavaBean field’s getter method, where the field is initialized. The following JSP markup contains a reference to a JavaBean named RandomBean and displays a field from the bean on the page:   <%-- Document : recipe02_03 Author : juneau --%>   <%@page contentType="text/html" pageEncoding="UTF-8"%> Recipe 2-3: Separating Business Logic from View Code Chapter 2 ■ JavaServer Pages 59 

Display a Random Number



Your random number is ${randomBean.randomNumber}. Refresh page to see another!

  The next code is that of the JavaBean class referenced in the JSP code, known as RandomBean:   package org.javaeerecipes.chapter02.recipe02_03;   import java.util.Random;   /** * Recipe 2-3 * @author juneau */ public class RandomBean { Random randomGenerator = new Random(); private int randomNumber = 0;   /** * @return the randomNumber */ public int getRandomNumber() { randomNumber = randomGenerator.nextInt(); return randomNumber; }   }   The resulting output for the page resembles the following, although the random number will be different every time the page is loaded:   Your random number is -1200578984. Refresh page to see another!  How It Works Sometimes embedding Java code directly into a JSP page can be helpful, and it can satisfy the requirement. However, in most cases, it is a good idea to separate any Java code from markup code that is used to create the web view. Doing so makes maintenance easier, and it allows a page developer to focus on creating nice-looking web pages rather than wading through Java code. In some organizations, a Java developer can then write the server-side business logic code, and a web developer can focus on the view. In many organizations today, the same person is performing both tasks, and using the MVC methodology can help separate the logic and increase productivity. Chapter 2 ■ JavaServer Pages 60 In the early days of JSP, embedding Java directly into a JSP page was the only way to go, but as time went on, the MVC paradigm caught on, and JSP has been updated to follow suit. As a best practice, it is good to use JSP tags to separate Java code from page markup. In the example, the element is used to reference a server- side JavaBean class so that the public fields and methods from that class, as well as private fields via public “getter” methods, can be incorporated into the JSP page. The jsp:useBean element requires that you provide an ID and a scope, along with a class name or a beanName. In the example, the id attribute is set to randomBean, and this id is used to reference the bean within the JSP page. The scope attribute is set to application, which means that the bean can be used from any JSP page within the application. Table 2-1 displays all the possible scopes and what they mean. The class attribute is set to the fully qualified name of the Java class that will be referenced via the name that is set with the id attribute, in this case, randomBean. Table 2-1.  jsp:useBean Element Scopes Scope Description page (default) The bean can be used within the same JSP page that contains the jsp:useBean element. request The bean can be used from any JSP page processing the same request. session The bean can be used from any JSP page within the same session as the JSP page that contains the jsp:useBean element that created the bean. The page that creates the bean must have a page directive with session="true". application The bean can be used from any JSP within the same application as the JSP page that created it. After the jsp:useBean element has been added to a page, JavaBean properties can be used in the JSP page, and public methods can be called from the page. The example demonstrates how to display the value of a JavaBean property using the ${ } notation. Any variable that contains a “getter” and a “setter” method in the JavaBean can be accessed from a JSP page by referencing the class member field in between the ${ and } character sequences, better known as an Expression Language expression. To learn more about EL expressions, please see Recipe 2-4. The following excerpt from the example demonstrates how to display the randomNumber field from the JavaBean:   Your random number is ${randomBean.randomNumber}. Refresh page to see another!   The key to separating business logic from view logic in the JSP technology is the jsp:useBean element. This will allow you to use JavaBean classes from within the JSP page, without embedding the code directly in the page. Separating business logic from view code can help make it easier to maintain code in the future and make the code easier to follow. 2-4. Yielding or Setting Values Problem You want to display values from a JavaBean in a JSP page. Furthermore, you want to have the ability to set values in a JSP page. Solution Expose the values from a JavaBean in a JSP page using EL expressions with the ${ bean.value } syntax. In the following JSP code, a Java class by the name of EasyBean will be used to hold the value that is entered into a text field by a user. The value will then be read from the bean and displayed on the page using EL expressions. Chapter 2 ■ JavaServer Pages 61 The following code shows a JSP page that contains an input form and displays the value that is entered into the text box:   <%-- Document : recipe02_04 Author : juneau --%>   <%@page contentType="text/html" pageEncoding="UTF-8"%> Recipe 2-4: Yielding and Setting Values
Use the input text box below to set the value, and then hit submit.

Set the field value:
The value contained within the field is currently:   Next, the JavaBean class, which is used to hold the value that is used by the page, looks like the following:   package org.javaeerecipes.chapter02.recipe02_04;   /** * Recipe 2-4: Yielding and Setting Values * @author juneau */ public class EasyBean implements java.io.Serializable { private String fieldValue;   public EasyBean(){ fieldValue = null; }   /** * @return the fieldValue */ Chapter 2 ■ JavaServer Pages 62 public String getFieldValue() { return fieldValue; }   /** * @param fieldValue the fieldValue to set */ public void setFieldValue(String fieldValue) { this.fieldValue = fieldValue; }   }   This simple example demonstrates how to enter a value, “set” it into the JavaBean variable, and then display it on the page. How It Works Perhaps one of the most useful web constructs is the input form, which allows a user to enter information into text boxes on the page and submit them to a server for processing. JSP makes it easy to submit values from an HTML form, and it is equally easy to display them back on a page. To do so, a field is declared in a Java class and accessor methods (aka getters and setters) are provided so that other classes can save values to the field and obtain values that are currently stored in it. Sometimes Java classes that contain fields with accessor methods are referred to as JavaBean classes. The classes can also contain other methods that can be used to perform tasks, but it is a best practice to keep JavaBeans as simple as possible. JavaBean classes should also implement java.io.Serializable so that they can be easily stored and resurrected. In the example for this recipe, a Java class named EasyBean contains a private field named fieldValue. The accessor methods getFieldValue and setFieldValue can be used to obtain and store the value in fieldValue, respectively. Those accessor methods are declared as public, and thus they can be used from another Java class or JSP page. The JSP page uses the jsp:useBean element to obtain a reference to the EasyBean class. The scope is set to page so that the class can be used only within the JSP page that contains the jsp:useBean element. Table 2-1, which can be found in the previous recipe, lists the different scopes available for use with the jsp:useBean element.     Next, an HTML form is defined in the JSP page with the POST method, and it contains an input field named fieldValue, which allows a user to enter a String of text that will be submitted as a request parameter when the form is submitted. Note that the form in the example does not have an action specified; this means that the same URL will be used for form submission, and the same JSP will be used for form submission and will be displayed again once the form is submitted. Since the JSP has a jsp:useBean element specified on the page, all request parameters will be sent to that bean when the page is submitted. The key to ensuring that the value entered into the fieldValue input text field is stored into the fieldValue variable within the Java class is using the jsp:setProperty element within the form. The jsp:setProperty element allows one or more properties to be set in a JavaBean class using the corresponding setter methods. In the example, is used to instantiate the EasyBean Java class, and is used to set the value that is entered within the fieldValue input text box to the fieldValue variable within the EasyBean class. The jsp:setProperty name attribute must equal the value of the jsp:useBean id attribute. The jsp:setProperty property attribute can equal the name of the field within the Java class that you Chapter 2 ■ JavaServer Pages 63 want to set in the bean, or it can be a wildcard * character to submit all input fields to the bean. The value attribute of jsp:setProperty can be used to specify a static value for the property. The following excerpt from the example shows how the jsp:setProperty tag is used:     Note■■   The ordering of the JSP elements is very important. must come before because the jsp:useBean element is responsible for instantiating its corresponding Java class. Since the JSP page is executed from the top of the page downward, the bean would be unavailable for use to any elements prior to when jsp:useBean is specified. When the user enters a value into the input field and submits the request, it is submitted as a request parameter to the Java class that corresponds to the jsp:useBean element for that page. There are a couple of different ways to display the data that has been populated in the JavaBean field. The example demonstrates how to use the jsp:getProperty element to display the value of the fieldValue variable. The element must specify a name attribute, which corresponds to the id of the Java class that was specified within the jsp:useBean element. It must also specify a property attribute, which corresponds to the name of the JavaBean property that you want to display. The following excerpt from the example demonstrates the use of the jsp:getProperty tag:     It is also possible to display the value of a JavaBean property using EL expressions, using the id of specified in the jsp:useBean element, along with the property name. To try this, you can replace the jsp:getProperty element with the following EL expression:   ${easyBean.fieldValue}   The JSP framework makes the development of web applications using Java technology much easier than using servlets. Input forms such as the one demonstrated in this example show how much more productive JSP is compared to standard servlet coding. As with anything, both servlets and JSP technology have their place in your toolbox. For creating simple data entry forms, JSP definitely takes the cake. 2-5. Invoking a Function in a Conditional Expression Problem You want to use a Java function to perform a conditional evaluation within your JSP. However, you do not want to embed Java code into your JSP page. Solution Code the function in a JavaBean class and then register the bean with the JSP via the tag. You will then need to register the function within a tag library descriptor (TLD) so that it can be made usable on the JSP page via a tag. Finally, set up a page directive for the TLD in which the function is registered, and use the function tag within the page. In the example that follows, a JSP page will use a function to tell the user whether a given Java type is a primitive type. The user will enter a String value into a text box, and that value will be submitted to a JavaBean field. The contents of the field will then be compared against a list of Java primitive types to determine whether it is a match. If the value entered into the field is a primitive, a message will be displayed to the user. ChaPTEr 2 ■ JavaSErvEr PagES 64 The following code is the Java class that contains the implementation of the function, which is going to be used from within the JSP. The bean also contains a field that will be used from the JSP page for setting and getting the value that is entered by the user. package org.javaeerecipes.chapter02.recipe02_05; /** * Recipe 2-5 * @author juneau */ public class ConditionalClass implements java.io.Serializable { private String typename = null; public static String[] javaTypes = new String[8]; public ConditionalClass(){ javaTypes[0] = "byte"; javaTypes[1] = "short"; javaTypes[2] = "int"; javaTypes[3] = "long"; javaTypes[4] = "float"; javaTypes[5] = "double"; javaTypes[6] = "boolean"; javaTypes[7] = "char"; } public static boolean isPrimitive(String value){ boolean returnValue = false; for(int x=0; x<=javaTypes.length-1; x++){ if(javaTypes[x].equalsIgnoreCase(value)){ returnValue = true; } } return returnValue; } /** * @return the typename */ public String getTypename() { return typename; } /** * @param typename the typename to set */ public void setTypename(String typename) { this.typename = typename; } } Chapter 2 ■ JavaServer Pages 65 The field typename will be used from the JSP page to set the value that is entered by the user and to retrieve it for passing to the function named isPrimitive();, which is used to compare the given value to a list of Java primitives. Next is a listing of the TLD that is used to register the function so that it can be used as a tag within the JSP. For simplicity, the TLD file is named functions.tld.   1.0 fct functions isPrimitive org.javaeerecipes.chapter02.recipe02_05.ConditionalClass boolean isPrimitive(java.lang.String)   Last is the JSP code that contains the page directive for using the TLD and the conditional call to the function isPrimitive() via a tag:   <%-- Document : recipe02_05 Author : juneau --%>   <%@page contentType="text/html" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jcp/jstl/core" prefix="c" %> <%@ taglib uri="/WEB-INF/tlds/functions.tld" prefix="fct" %> Recipe 2-5: Invoking a Function in an Expression

Name one of the primitive Java types:


Chapter 2 ■ JavaServer Pages 66  ${ conditionalBean.typename } is a primitive type. ${ conditionalBean.typename } is not a primitive type.   Following the strategy used in this solution, you can create a conditional test that is usable via a JSP tag for your pages. How It Works You need to take a few different steps before a Java function can become accessible from a JSP page. One of the most commonly overlooked conditions is that the function must be declared with a static modifier in the Java class. In the example for this recipe, the function isPrimitive is declared as static, and it returns a boolean value indicating whether the web page user types the name of a Java primitive type. The next step toward making a function accessible via a JSP page is to register it with a TLD. In the example, a TLD named functions.tld is created, although if there is already a custom TLD in your application, then you could register the function with it rather than creating an additional one if you want. The TLD in this example has a short-name attribute of fct, which will be used from within JSP tags. To actually register the function, you must create a function element within the TLD, provide a function name, indicate the class that the function resides within, and, finally, specify the function signature.   isPrimitive org.javaeerecipes.chapter02.recipe02_05.ConditionalClass boolean isPrimitive(java.lang.String)   The function is now ready for use within the JSP. To make the function accessible via the JSP, register the TLD that contains the function element by including a taglib directive specifying the uri and prefix for the TLD. The uri is the path to the TLD, and the prefix should match the name given in the short-name element of the TLD. The following excerpt from the JSP in this example shows the taglib directive:   <%@ taglib uri="/WEB-INF/tlds/functions.tld" prefix="fct" %>   The function will now be accessible via an EL expression within the JSP by specifying the taglib prefix along with the name of the function as it is registered in the TLD. The EL expression in the example calls the function, passing the typename parameter. The isPrimitive function is used to determine whether the text contained within the typename bean field is equal to one of the Java primitive types.     Chapter 2 ■ JavaServer Pages 67 The solution in this recipe also uses the Java Standard Tag Library (JSTL) core. Depending upon the server environment being used, this may be a separate download. The JSTL provides an extension to the standard set of tags provided with the JSP API. For more information regarding JSTL, please refer to the online documentation, which can be found at www.oracle.com/technetwork/java/index-jsp-135995.html. The JSTL tag can be used to test conditions, executing the markup between its opening and closing tags if the condition test returns a true value. Not surprisingly, the tag includes a test attribute that specifies an EL expression that indicates the test that needs to be performed. In the example, the isPrimitive function is called within the EL expression, passing the bean value. If the test returns a true, then a message is printed indicating that the given value is equal to a Java primitive type. Another test follows the first in the example, and this time it tests to ensure that the property value is not equal to null and also that it is not a Java primitive type. Expression Language is used to determine whether the property value is equal to null via the ne expression. The and expression ties both the first and second conditional expressions together within the EL expression, meaning that both of the expressions must evaluate to a true value in order for the condition to be met. If both conditions are met, then the value specified by the user is not a Java primitive type, and a corresponding message is printed.   ${ conditionalBean.typename } is not a primitive type.   It takes only a few easy steps to create a conditional function for use within JSPs. First, in the JavaBean class, you must create a public static function, which returns a boolean value. Second, create a TLD, which will make the function available via a JSP tag. Lastly, use the custom tag from within the JSP page along with JSTL conditional test tags to display the content conditionally. 2-6. Creating a JSP Document Problem Rather than using standard HTML format, you want to ensure that your JSP code follows the XML standard and contains only valid HTML and JSP tags. Solution Create a JSP document rather than a standard JSP. A JSP document is an XML-based representation of a standard JSP document that conforms to the XML standard. The following JSP document contains the same code that is used in the JSP code for Recipe 2-5, but it uses the JSP document format instead. As you can see, not much is different because well-formed tags were already used to create the standard JSP document. The page is also saved with an extension of jspx rather than jsp.     Chapter 2 ■ JavaServer Pages 68

Name one of the primitive Java types:


 ${ conditionalBean.typename } is a primitive type.    ${ conditionalBean.typename } is not a primitive type.     This JSP document will yield the same output as the one in Recipe 2-5. However, a well-formed document will be enforced, and this will exclude the use of scripting elements within the page. How It Works As foreshadowed in Recipe 2-3, separating business logic from markup code can be important for many reasons. Standard JSP pages can adhere to the MVC paradigm, but they are not forced into doing so. Sometimes it makes sense to enforce the separation of business logic, by strictly adhering to a well-formed XML document using only JSP tags to work with server-side Java classes. Well-formed means that there should be only one root element, and each starting tag must have a corresponding ending tag. Creating a JSP document is one answer because such documents enforce well-formed XML and do not allow scripting elements to be used within the JSP page. Several JSP tags can be used to communicate with Java classes, perform JSP-specific functionality, and make markup easy to follow. As such, modern JSP-based applications should make use of well-formed JSP documents utilizing such JSP tags, rather than embedding scripting elements throughout markup. Table 2-2 describes what the different JSP tags do. Chapter 2 ■ JavaServer Pages 69 Table 2-2.  JSP Tags Tag Description Defines attributes for a JSP page. Defines an element body. Defines page declarations. Defines page includes and page directives. Executes the body of the JSP tag that is used by the calling JSP page to invoke the tag. Generates an XML element dynamically. Inserts the value of a scripting language expression, converted into a string. Forwards a request to another page. The new page can be HTML, JSP, or servlet. Obtains the value of a bean property and places it in the page. Includes another JSP or web resource in the page. Invokes a specified JSP fragment. Specifies the document type declaration. Executes an applet or bean with the specified plug-in. Defines standard elements and tag library namespaces. Embeds code fragment into a page if necessary. Sets specified value(s) into a bean property. Encloses template data. References and instantiates (if needed) a JavaBean class using a name and providing a scope. Creating a well-formed JSP can lead to easier development, ease of maintenance, and better overall design. Since it is so important, the remaining recipes in this chapter will use the JSP document format. 2-7. Embedding Expressions in EL Problem You want to use some conditional expressions and/or arithmetic within your JSP without embedding Java code using scripting elements. Solution Use EL expressions within JSP tags to perform conditional and/or arithmetic expressions. This solution will look at two examples of EL expressions. The first example demonstrates how to perform conditional logic using EL expressions. Note that the JSTL tag library is also used in this case, to conditionally display a message on the page if the expression results to true.   Chapter 2 ■ JavaServer Pages 70 Recipe 2-7: Embedding Expressions in EL

Conditional Expressions

The following portion of the page will only display conditional expressions which result in a true value.

The conditional expression (1 + 1 == 2) results in TRUE.
The conditional expression (x == y) results in TRUE.
The conditional expression ((100/10) > 5) results in TRUE.
The conditional expression (20 mod 3 eq 2) results in TRUE.
  This JSP page will result in the following output being displayed:   ... The conditional expression (1 + 1 == 2) results in TRUE. The conditional expression ((100/10) > 5) results in TRUE. The conditional expression (20 mod 3 eq 2) results in TRUE. ...   Chapter 2 ■ JavaServer Pages 71 Arithmetic expressions can also be evaluated using EL. The following JSP code demonstrates some examples of using arithmetic within EL:   Recipe 2-7: Embedding Expressions in EL

Arithmetic Expressions

The following expressions demonstrate how to perform arithmetic using EL.

10 - 4 = ${10 - 4}
85 / 15 = ${85 / 15}
847 divided by 6 = ${847 div 6}
${expBean.num1} * ${expBean.num2} = ${expBean.num1 * expBean.num2}       The preceding JSP will result in the following output being displayed:   ... 10 - 4 = 6 85 / 15 = 5.666666666666667 847 divided by 6 = 141.16666666666666 5 * 634.324 = 3171.62 ...  How It Works The JSP technology makes it easy to work with expressions. Conditional page rendering can be performed using a combination of EL value expressions, which are enclosed within the ${ } character sequences, and JSTL tags. Arithmetic expressions can also be performed using EL expressions. To make things easier, the Expression Language contains keywords or characters that can be used to help form expressions. The example for this recipe contains various expressions and conditional page rendering using the JSTL tag. Chapter 2 ■ JavaServer Pages 72 In the first JSP page displayed in the example, there are some examples of conditional page rendering. To use the tag to perform the conditional tests, you must be sure to import the JSTL tag library with the JSP page. To do so, add an import for the JSTL tag library and assign it to a character or string of characters. In the following excerpt from the recipe, the JSTL library is assigned to the character c:     An EL value expression is contained within the ${ and } character sequences. Anything within these characters will be treated as EL, and as such, the syntax must be correct, or the JSP page will not be able to compile into a servlet, and it will throw an error. All expressions using the ${ } syntax are evaluated immediately, and they are read-only expressions. That is, no expressions using this syntax can be used to set values into a JavaBean property. The JSP engine first evaluates the expression, and then it converts into a String and lastly returns the value to the tag handler. Four types of objects can be referenced within a value expression. Those are JavaBean components, collections, enumerated types, and implicit objects. If using a JavaBean component, the JavaBean must be registered with the JSP page using the jsp:useBean element (see Recipe 2-3 for details). Collections or enumerated types can also be referenced from a JavaBean that has been registered with the page. Implicit objects are those that allow access to page context, scoped variables, and other such objects. Table 2-3 lists different implicit objects that can be referenced from within EL expressions. Table 2-3.  Implicit JSP Objects Object Type Description pageContext Context Provides access to the context of the page and various subobjects servletContext Page context Context for JSP page servlet and web components session Page context Session object for the client request Page context Request that invoked the execution of the page response Page context Response that is returned by the JSP param N/A Responsible for mapping parameter names to values paramValues N/A Maps request parameter to an array of values header N/A Responsible for mapping a header name to a value headerValues N/A Maps header name to an array of values cookie N/A Maps a cookie name to a single cookie initParam N/A Maps a context initialization parameter to a value pageScope Scope Maps page scope variables requestScope Scope Maps request scope variables sessionScope Scope Maps session scope variables applicationScope Scope Maps application scope variables Chapter 2 ■ JavaServer Pages 73 The following are some examples of expressions that make use of JavaBean components, collections, enumerated types, and implicit objects:   // Displays the value of a variable named myVar within a JavaBean referenced as elTester ${ elTester.myVar } // Does the same thing as the line above ${ elTester["myVar"] }   // Evaluates an Enumerated Type in which myEnum is an instance of MyEnum ${ myEnum == "myValue" } // Reference a getter method of the Enum named getTestVal() ${ myEnum.testVal}   // References a collection named myCollection within the JavaBean referenced as elTester ${ elTester.myCollection }   // Obtain the parameter named "testParam" ${ param.testParam } // Same as: request.getParameter("testParam") // Obtain session attribute named "testAttr" ${ sessionScope.testAttr } // Same as: session.getAttribute("testAttr")   In the recipe example, the tag is used to test a series of value expressions and conditionally display page content. The test attribute of is used to register a test condition, and if the test condition returns a true result, then the content contained between the starting and ending tags is displayed. The following excerpt from the example demonstrates how a test is performed:   The conditional expression (x == y) results in TRUE.
  EL expressions can contain a series of reserved words that can be used to help evaluate the expression. For instance, the following expression utilizes the gt reserved word to return a value indicating whether the value returned from the calculation of 100/10 is greater than 5:   The conditional expression ((100/10) > 5) results in TRUE.
  Table 2-4 lists all the JSP EL expression reserved words and their meanings. ChaPTEr 2 ■ JavaSErvEr PagES 74 Arithmetic expressions are demonstrated by the second example in this recipe. The following arithmetic operators can be utilized within expressions: + (addition), - (binary and unary), * (multiplication), / and div (division), %, and mod (modulus)• and, &&, or, ||, not, !• ==, !=, <, >, <=, >=• X ? Y : Z (ternary conditional)• Entire chapters of books have been written on the use of EL expressions within JSPs. This recipe only touches upon the possibilities of using value expressions. The best way to get used to expressions is to create a test JSP page and experiment with the different options that are available. 2-8. Accessing Parameters in Multiple Pages Problem You want to access a parameter from within multiple pages of your web application. Table 2-4. EL Expression Reserved Words Reserved Word Description and Combines expressions and returns true if all of them evaluate to true or Combines expressions and returns true if one of them evaluates to true not Negates an expression eq Equal ne Not equal lt Less than gt Greater than le Less than or equal ge Greater than or equal true True value false False value null Null value instanceof Used to test whether an object is an instance of another object empty Determines whether a list or collection is empty div Divided by mod Modulus Chapter 2 ■ JavaServer Pages 75 Solution Create an input form to submit parameters to the request object, and then utilize the request object to retrieve the values in another page. In the example that follows, a JSP page that contains an input form is used to pass values to another JSP page by setting the HTML form action attribute to the value of the JSP page that will utilize the parameters. In the case of this example, the receiving JSP page merely displays the parameter values, but other work could be performed as well. The following JSP code demonstrates the use of an input form to save parameters into the request object and pass them to a page named recipe02_08b.jspx:   Recipe 2-8: Passing Parameters

Passing Parameters

The following parameters will be passed to the next JSP.

Param 1:
Param 2:
Param 3:
  The next JSP code receives the parameters and displays their values:     Chapter 2 ■ JavaServer Pages 76 Recipe 2-8: Passing Parameters

Passing Parameters

The following parameters will were passed from the original JSP.

Param 1: request.getParameter("param1")
Param 2: request.getParameter("param2")
Param 3: request.getParameter("param3")
OR using value expressions
Param 1: ${ param.param1 }
Param 2: ${ param.param2 }
Param 3: ${ param.param3 }
    As you can see, a couple of variations can be used to display the parameter values. Both of the variations will display the same result. How It Works Request parameters are one of the most useful features of web applications. When a user enters some data into a web form and submits the form, the request contains the parameters that were entered into the form. Parameters can also be statically embedded within a web page or concatenated onto a URL and sent to a receiving servlet or JSP page. The data contained in request parameters can then be inserted into a database, redisplayed on another JSP page, used to perform a calculation, or a myriad of other possibilities. The JSP technology provides an easy mechanism for using request parameters within other JSP pages, and the example in this recipe demonstrates how to do just that. Note■■ request parameters are always translated into String values. Chapter 2 ■ JavaServer Pages 77 Note that in the example, the first JSP page uses a simple HTML form to obtain values from a user and submit them to the request. Another JSP page named recipe02_08b.jspx is set as the form action attribute, so when the form is submitted, it will send the request to recipe02_08b.jspx. The input fields on the first JSP page specify both an id attribute and a name attribute, although only the name attribute is required. The name that is given to the input fields is the name that will be used to reference the value entered into it as a request parameter. Note■■   It is a good programming practice to always include an id attribute. The ID is useful for performing work with the DOM and for referencing elements via a scripting language such as JavaScript. The receiving action, recipe02_08b.jspx in this example, can make a call to response.getParameter(), passing the name of a parameter (input field name) to obtain the value that was entered into its corresponding text field. To adhere to JSP document standards, the scriptlet containing the call to response.getParameter() must be enclosed within tags. The following excerpt demonstrates how this is done:   Param 1: request.getParameter("param1")   Optionally, an EL expression can contain a reference to the implicit param object and obtain the request parameter in the same way. When the expression ${param.param1} is called, it is evaluated by the JSP engine, and it is translated into response.getParameter("param1"). The following excerpt demonstrates this use of EL expressions:   Param 1: ${ param.param1 }   Either technique will perform the same task; the named request parameter will be obtained and displayed on the page. 2-9. Creating a Custom JSP Tag Problem You want to create a JSP tag that provides custom functionality for your application. Solution Create a custom JSP tag using JSP 2.0 simple tag support. Suppose you want to create a custom tag that will insert a signature into the JSP where the tag is placed. The custom tag will print out a default signature, but it will also accept an authorName attribute, which will include a given author's name to the signature if provided. To get started, you'll first need to define a Java class that extends the SimpleTagSupport class. This class will provide the implementation for your tag. The following code is the implementation for a class named Signature, which provides the implementation for the custom tag. Note■■   To compile the following code, you will need to add javax.servlet.jsp to classpath:  cd recipe02_09 javac -cp ...\glassfish4\glassfish\modules\javax.servlet.jsp-api.jar *.java  Chapter 2 ■ JavaServer Pages 78 package org.javaeerecipes.chapter02.recipe02_09;   import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.SimpleTagSupport;   /** * Recipe 2-9: Creating a Custom JSP Tag * @author juneau */ public class Signature extends SimpleTagSupport {   private String authorName = null;   /** * @param authorName the authorName to set */ public void setAuthorName(String authorName) { this.authorName = authorName; }   @Override public void doTag() throws JspException { PageContext pageContext = (PageContext) getJspContext(); JspWriter out = pageContext.getOut();   try { if(authorName != null){ out.println("Written by " + authorName); out.println("
"); } out.println("Published by Apress");   } catch (Exception e) { System.out.println(e); }   } }   Next, a TLD to be created to map the Signature class tag implementation to a tag. The TLD that includes the custom tag mapping is listed here:   1.0 cust custom Chapter 2 ■ JavaServer Pages 79 signature org.javaeerecipes.chapter02.recipe02_09.Signature empty authorName true false   Once the class implementation and the TLD are in place, the tag can be used from within a JSP page. The following JSP code is an example of using the custom tag on a page:   Recipe 2-9: Creating a Custom JSP Tag

Custom JSP Tag

The custom JSP tag is used as the footer for this page.

      The custom tag output will now be displayed in place of the cust:signature element within the JSP page. How It Works One of the most useful new features of JSP 2.0 was the inclusion of the SimpleTagSupport class, which provides an easier way for developers to create custom tags. Prior to the 2.0 release, custom tag creation took a good deal of more work, because the developer had to provide much more code to implement the tag within the tag's implementation class. The SimpleTagSupport class takes care of much implementation for the developer so that the only thing left to do is implement the doTag method in order to provide an implementation for the custom tag. Chapter 2 ■ JavaServer Pages 80 In the example for this recipe, a custom tag is created that will print out a signature on the JSP page in the position where the tag is located. To create a custom tag implementation, create a Java class that will extend the SimpleTagSupport class, and provide an implementation for the doTag method. The example class also contains a field named authorName, which will be mapped within the TLD as an attribute for the custom tag. In the doTag method, a handle on the JSP page context is obtained by calling the getJspContext method. getJspContext is a custom method that is implemented for you within SimpleTagSupport and makes it easy to get ahold of the JSP page context. Next, to provide the ability to write to the JSP output, a handle is obtained on the JspWriter by calling PageContext's getOut method.   PageContext pageContext = (PageContext) getJspContext(); JspWriter out = pageContext.getOut();   The next lines within doTag provide the implementation for writing to the JSP output via a series of calls to out.println. Any content that is passed to out.println will be displayed on the page. Note that in the example, the authorName field is checked to see whether it contains a null value. If it does not contain a null value, then it is displayed on the page; otherwise, it is omitted. Therefore, if the tag within the JSP page contains a value for the authorName attribute, then it will be printed on the page. The out.println code is contained within a try-catch block in case any exceptions occur. Note■■   To allow your tag to accept scriptlets, you will need to use the Classic Tag Handlers. The Classic Tag handlers existed before the JSP 2.0 era and can still be used today alongside the Simple Tag Handlers. The Simple Tag Handlers revolve around the doTag() method, whereas the Classic Tag Handlers deal with a doStartTag() method and a doEndTag() method, as well as others. Since the Simple Tag Handlers can be used alongside the Classic Tag Handlers, it is possible to use some of the more complex Classic Tag methods, while utilizing Simple Tag methods in the same application. This eases the transition from the Classic Tag Handlers to the Simple Tag Handlers. For more information regarding the differences between the two APIs, please see some online documentation by searching for the keywords Simple vs. Classic Tag Handlers. That's it; the implementation for the tag is complete. To map the implementation class to the Document Object Model (DOM) via a tag name, a TLD must contain a mapping to the class. In the example, a TLD is created named custom.tld, and it contains the mapping for the class. The short-name element specifies the name that must be used within the JSP page to reference the tag. The uri element specifies the name of the TLD, and it is used from within the JSP page to reference the TLD file itself. The meat of the TLD is contained within the tag element. The name element is used to specify the name for the tag, and it will be used within a JSP page in combination with the short-name element to provide the complete tag name. The tag-class element provides the name of the class that implements the tag, and body-content specifies a value to indicate whether the body content for the JSP page will be made available for the tag implementation class. It is set to empty for this example. To specify an attribute for the tag, the attribute element must be added to the TLD, including the name, rtexprvalue, and required elements. The name element of attribute specifies the name of the attribute, rtexprvalue indicates whether the attribute can contain an EL expression, and required indicates whether the attribute is required. To use the tag within a JSP page, the custom.tld TLD must be mapped to the page within the element in a JSP document or a taglib directive within a standard JSP. The following lines show the difference between these two:   xmlns:cust="custom"   <%@taglib prefix="cust" uri="custom" %>   Chapter 2 ■ JavaServer Pages 81 To use the tag within the page, simply specify the TLD short-name along with the mapping name for the tag implementation and any attributes you want to provide.     Creating custom tags within JSP is easier than it was in the past. Custom tags provide developers with the ability to define custom actions and/or content that can be made accessible from within a JSP page via a tag rather than scriptlets. Custom tags help developers follow the MVC architecture, separating code from business logic. 2-10. Including Other JSPs into a Page Problem Rather than coding the same header or footer into each JSP, you want to place the content for those page sections into a separate JSP page and then pull them into JSP pages by reference. Solution Use the tag to embed other static or dynamic pages in your JSP page. The following example demonstrates the inclusion of two JSP pages within another. One of the JSP pages is used to formulate the header of the page, and another is used for the footer. The following page demonstrates the main JSP page, which includes two others using the tag. The JSPX files named recipe02_10-header.jspx and recipe02_10-footer.jspx are included within the body of the main JSP page in order to provide the header and footer sections of the page.     Recipe 2-09: Including Other JSPs into a Page

This is the body of the main JSP.

Both the header and footer for this page were created as separate JSPs.

      Chapter 2 ■ JavaServer Pages 82 Next is the JSP code that comprises the page header. It’s nothing fancy but is a separate JSP page nonetheless.    

This is the page header

  The next JSP code makes up the page footer:    

This is the page footer

    In the end, these three pages create a single page that contains a header, a body, and a footer. How It Works Including other JSP pages helps increase developer productivity and reduces maintenance time. Using this technique, a developer can extract any JSP features that appear in multiple pages and place them into a separate JSP page. Doing so will allow a single point of maintenance when one of these features needs to be updated. To include another page within a JSP page, use the tag. The tag allows embedding a static file or another web component. The tag includes a page attribute, which is used to specify the relative URL or an expression that results in another file or web component to include in the page. Note■■   The tag also has an optional flush attribute, which can be set to either true or false to indicate whether the output buffer should be flushed prior to the page inclusion. The default value for the flush attribute is false. Optionally, clauses can be placed between the opening and closing tags to pass one or more name-value pairs to the included resource if the resource is dynamic. An example of performing this technique would resemble something like the following lines of code. In the following lines, a parameter with a name of bookAuthor and a value of Juneau is passed to the header JSP page.     The ability to include other content within a JSP page provides a means to encapsulate resources and static content. This allows developers to create content once and include it in many pages. Chapter 2 ■ JavaServer Pages 83 2-11. Creating an Input Form for a Database Record Problem You want to create a JSP page that will be used to input information that will be inserted as a database record. Solution Create an input form and use a Java servlet action method to insert the values into the database. This solution requires a JSP document and a Java servlet in order to complete the database input form. In the following example, an input form is created within a JSP document to populate records within a database table named RECIPES. When the user enters the information into the text fields on the form and clicked the submit button, a servlet is called that performs the database insert transaction. The following code is the JSP document that is used to create the input form for the database application:   Recipe 2-11: Creating an Input Form

Recipe Input Form

Please insert recipe details using the text fields below.

${ recipeBean.message }
Recipe Number:
Recipe Name:
Recipe Description:
Recipe Text:

  ChaPTEr 2 ■ JavaSErvEr PagES 84 Next is the code for a servlet named RecipeServlet. It is responsible for reading the request parameters from the JSP document input form and inserting the fields into the database. package org.javaeerecipes.chapter02.recipe02_11; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Recipe 2-11: Creating an Input Form * @author juneau */ @WebServlet(name = "RecipeServlet", urlPatterns = {"/RecipeServlet"}) public class RecipeServlet extends HttpServlet { /** * Processes requests for both HTTP * GET and * POST methods. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); int result = -1; try { /* * TODO Perform validation on the request parameters here */ result = insertRow (request.getParameter("recipeNumber"), request.getParameter("name"), request.getParameter("description"), request.getParameter("text")); out.println(""); out.println(""); out.println("Servlet RecipeServlet"); out.println(""); out.println(""); Chapter 2 ■ JavaServer Pages 85 out.println("

Servlet RecipeServlet at " + request.getContextPath() + "

"); out.println("

");   if(result > 0){ out.println("Record successfully inserted!"); out.println("

Insert another record"); } else { out.println("Record NOT inserted!"); out.println("

Try Again"); }   out.println(""); out.println(""); } finally { out.close(); } }   public int insertRow(String recipeNumber, String name, String description, String text) {   String sql = "INSERT INTO RECIPES VALUES(" + "RECIPES_SEQ.NEXTVAL,?,?,?,?)"; PreparedStatement stmt = null; int result = -1; try { CreateConnection createConn = new CreateConnection(); Connection conn = createConn.getConnection(); stmt = (PreparedStatement) conn.prepareStatement(sql); stmt.setString(1, recipeNumber); stmt.setString(2, name); stmt.setString(3, description); stmt.setString(4, text); // Returns row-count or 0 if not successful result = stmt.executeUpdate(); if (result > 0){ System.out.println("-- Record created --"); } else { System.out.println("!! Record NOT Created !!"); } } catch (SQLException e) { e.printStackTrace(); } finally { if (stmt != null) { try { stmt.close(); } catch (SQLException ex) { Chapter 2 ■ JavaServer Pages 86 ex.printStackTrace(); } }   } return result; }    @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); }    @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } }   If the request is successful, the record will be inserted into the database, and the user will be able to click a link to add another record. Of course, in a real-life application, you would want to code some validation using JavaScript either within the input form or within the server-side Java code to help ensure database integrity. How It Works A fundamental task to almost every enterprise application is the use of a database input form. Database input forms make it easy for end users to populate database tables with data. When using JSP technology along with servlets, this operation can become fairly simple. As you have seen in the example to this recipe, writing a JSP input form is straightforward and can be coded using basic HTML. The key is to set up a Java servlet to receive a submitted request and process the records using the servlet. This provides an easy mechanism for separating web content from the application logic. In the example, a JSP document named recipe02_11.jspx contains a standard HTML form with a method of POST and an action of /JavaEERecipes/RecipeServlet. The input form contains four fields, which map to database columns into which the data will eventually be inserted. The input tags contain the name of four corresponding fields (recipeNumber, name, description, and text), which will be passed to the form action when submitted. As you can see, the only reference to the Java code is the name of the servlet that is contained within the form action attribute. The Java servlet named RecipeServlet is responsible for obtaining the request parameters that were submitted via the JSP document, validating them accordingly (not shown in the example), and inserting them into the database. When the page is submitted, RecipeServlet is invoked, and the request is sent to the doPost method since the HTML action method is POST. Both the doGet and doPost methods are really just wrapper methods for a processing method named processRequest, which is responsible for most of the work. The processRequest method is responsible for obtaining the request parameters, inserting them into the database, and sending a response to the client. A PrintWriter object is declared and created by making a call to response.getWriter() first because this object will be used later to help form the response that is sent to the client. Next, an int value named result is set up and initialized to -1. This variable will be used for determining whether the SQL insert worked or failed. After those declarations, a try-catch block is opened, and the first line of the try block is a call to the insertRow method, passing the request parameters as values. The result variable is going to accept the int value that is returned from the execution of the insertRows method, indicating whether the insert was successful.   Chapter 2 ■ JavaServer Pages 87 result = insertRow (request.getParameter("recipeNumber"), request.getParameter("name"), request.getParameter("description"), request.getParameter("text"));   As such, an SQL insert statement is assigned to a String named sql, and it is set up using the PreparedStatement format. Each question mark in the SQL string corresponds to a parameter that will be substituted in the string when the SQL is executed.   String sql = "INSERT INTO RECIPES VALUES(" + "RECIPES_SEQ.NEXTVAL,?,?,?,?)";   Next, a PreparedStatement and int values are initialized, and then a try-catch-finally block is opened, which will contain the SQL insert code. Within the block, a Connection object is created by calling a helper class named CreateConnection. If you want to read more about this helper class, then you can read Chapter 7 on JDBC. For now, all you need to know is that CreateConnection will return a database connection that can then be used to work with the database. If for some reason the connection fails, the catch block will be executed, followed by the finally block. A PreparedStatement object is created from the successful connection, and the SQL string that contains the database insert is assigned to it. Each of the request parameter values, in turn, is then set as a parameter to the PreparedStatement. Lastly, the PreparedStatement’s executeUpdate method is called, which performs an insert to the database. The return value of executeUpdate is assigned to the result variable and then returned to the processRequest method. Once the control is returned to processRequest, the servlet response is created using a series of PrintWriter statements. If the insert was successful, then a message indicating success is displayed. Likewise, if unsuccessful, then a message indicating failure is displayed. Developing database input forms with JSP is fairly easy to do. To preserve the MVC structure, using a Java servlet for handing the request and database logic is the best choice. 2-12. Looping Through Database Records Within a Page Problem You want to display the records from a database table on your JSP page. Solution Encapsulate the database logic in a Java class and access it from the JSP page. Use the JSTL c:forEach element to iterate through the database rows and display them on the page. Two Java classes would be used for working with the data in this situation. One of the classes would represent the table, which you are querying from the database, and it would contain fields for each column in that table. Another JavaBean class would be used to contain the database business logic for querying the database. The example for this recipe will display the first and last names of each author contained within the AUTHORS database table. The following code is used to create the JSP document that will display the data from the table using a standard HTML-based table along with the JSTL tag to loop through the rows:   Chapter 2 ■ JavaServer Pages 88   Recipe 2-12: Looping Through Database Records within a Page

Authors

The authors from the books which Josh Juneau has worked on are printed below.

${ author.first } ${ author.last }
  As you can see, is used to loop through the items contained within ${authorBean.authorList}. Each item within the list is an object of type Author. The following Java code is that of the Author class, which is used for holding the data contained within each table row:   package org.javaeerecipes.chapter02.recipe02_12;   /** * * @author juneau */ public class Author implements java.io.Serializable { private int id; private String first; private String last;   public Author(){ id = -1; first = null; last = null; }   /** * @return the id */ public int getId() { return id; } Chapter 2 ■ JavaServer Pages 89   /** * @param id the id to set */ public void setId(int id) { this.id = id; }   /** * @return the first */ public String getFirst() { return first; }   /** * @param first the first to set */ public void setFirst(String first) { this.first = first; }   /** * @return the last */ public String getLast() { return last; }   /** * @param last the last to set */ public void setLast(String last) { this.last = last; } }   Lastly, the JSP document makes reference to a JavaBean named AuthorBean, which contains the business logic to query the data and return it as a list to the JSP page. The following code is what is contained within the AuthorBean class:   package org.javaeerecipes.chapter02.recipe02_12;   import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.javaeerecipes.common.CreateConnection;   Chapter 2 ■ JavaServer Pages 90 /** * Recipe 2-12 * @author juneau */ public class AuthorBean implements java.io.Serializable {   public static Connection conn = null; private List authorList = null;    public AuthorBean(){   }   public List queryAuthors(){ String sql = "SELECT ID, FIRST, LAST FROM BOOK_AUTHOR"; List authorList = new ArrayList(); PreparedStatement stmt = null; ResultSet rs = null; int result = -1; try { CreateConnection createConn = new CreateConnection(); conn = createConn.getConnection(); stmt = (PreparedStatement) conn.prepareStatement(sql);   // Returns row-count or 0 if not successful rs = stmt.executeQuery(); while (rs.next()){ Author author = new Author(); author.setId(rs.getInt("ID")); author.setFirst((rs.getString("FIRST"))); author.setLast(rs.getString("LAST")); authorList.add(author); } } catch (SQLException e) { e.printStackTrace(); } finally { if (stmt != null) { try { stmt.close(); } catch (SQLException ex) { ex.printStackTrace(); } }   } return authorList; }   Chapter 2 ■ JavaServer Pages 91 public List getAuthorList(){ authorList = queryAuthors(); return authorList; } }   The names of the authors contained within the records in the table will be displayed on the page. How It Works Almost any enterprise application performs some sort of database querying. Oftentimes results from a database query are displayed in a table format. The example in this recipe demonstrates how to query a database and return the results to a JSP page for display in a standard HTML table. The JSP page in this example makes use of the JSTL c:forEach element to iterate through the results of the database query. Note that there is more than one way to develop this type of database query using JSP; however, the format demonstrated in this recipe is most recommended for use in a production enterprise environment. As mentioned previously, the JSP page in this recipe uses a combination of the jsp:useBean element and the c:forEach element to iterate over the results of a database query. The logic for querying the database resides within a server-side JavaBean class that is referenced within the jsp:useBean element on the page. In the example, the JavaBean is named AuthorBean, and it is responsible for querying a database table named AUTHORS and populating a list of Author objects with the results of the query. When the c:forEach element is evaluated with the items attribute set to ${authorBean.authorList}, it calls upon the JavaBean method named getAuthorList because JSP expressions always append "get" to a method call behind the scenes and also capitalizes the first letter of the method name within the call. When the getAuthorList method is called, the authorList field is populated via a call to queryAuthors. The queryAuthors method utilizes a Java Database Connectivity (JDBC) database call to obtain the authors from the AUTHORS table. A new Author object is created for each row returned by the database query, and each new Author object is, in turn, added to the authorList. In the end, the populated authorList contains a number of Author objects, and it is returned to the JSP page and iterated over utilizing the c:forEach element. The c:forEach element contains an attribute named var, and this should be set equal to a string that will represent each element in the list that is being iterated over. The var is then used between the opening and closing c:forEach element tags to reference each element in the list, printing out each author's first and last names. This recipe provides some insight on how to combine the power of JSTL tags with other technologies such as JDBC to produce very useful results. To learn more about the different JSTL tags that are part of JSP, please visit the online documentation at www.oracle.com/technetwork/java/jstl-137486.html. To learn more about JDBC, please read Chapter 7 of this book. 2-13. Handling JSP Errors Problem You want to display a nicely formatted error page if a JSP page encounters an error. Solution Create a standard error page, and forward control to the error page if an exception occurs within the JSP page. The following JSP document, in JSP format (not JSPX), demonstrates a standard error page to display if an error occurs within a JSP application. If an exception occurs within any JSP page in the application, the following error page will be displayed. Chapter 2 ■ JavaServer Pages 92 Note■■   The example in the solution for this recipe uses the JSTL fmt library, which provides convenient access to formatting capabilities that allow for localization of text as well as date and number formatting. Text localization capabilities allow locales to be set so that text can be formatted into different languages, depending upon the user locale. Tags used for date manipulation make it easy for developers to format dates and times easily within a JSP page and also provide a way to parse dates and times for data input. Lastly, number-formatting tags provide a way to format and parse numeric data within pages. To learn more about the JSTL fmt tag library, please refer to the online documentation at http://jstl.java.net/.  <%-- Document : recipe02_13_errorPage Author : juneau --%>   <%@ page contentType="text/html" pageEncoding="UTF-8"%> <%@ page isErrorPage="true" %> <%@ taglib uri="http://java.sun.com/jcp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jcp/jstl/fmt" prefix="fmt" %> JSP Error Page

Error Encountered



The application has encountered the following error:
: ${pageContext.errorData.statusCode}  

  For example, the following JSP would create an error (NullPointerException) if the parameter designated as param is null. If this occurs, the indicated error page would be displayed.     Chapter 2 ■ JavaServer Pages 93 Recipe 2-13:

There is an error on this page

This will produce an error: if (request.getParameter("param").equals("value")) { System.out.println("test"); }

    How It Works One of the most annoying issues for users while working with applications is when an error is thrown. A nasty, long stack trace is often produced, and the user is left with no idea how to resolve the error. It is better to display a nice and user-friendly error page when such an error occurs. The JSP technology allows an error page to be designated by adding a page directive to each JSP page that may produce an error. The directive should designate an error page that will be displayed if the page containing the directive produces an error. The second JSP document in the solution to this recipe demonstrates a JSP page that will throw an error if the parameter being requested within the page is null. If this were to occur and there were no error page specified, then a NullPointerException error message would be displayed. However, this JSP indicates an error page by designating it within a page directive using the following syntax:     When an error occurs on the example page, recipe02_13.errorPage.jsp is displayed. The first JSP document listed in the solution to this recipe contains the sources for the recipe02_13.errorPage.jsp page. It is flagged as an error page because it includes a page directive indicating as such:   <%@ page isErrorPage="true" %>   An error page is able to determine the error code, status, exception, and an array of other information by using the pageContext implicit object. In the example, the ${pageContext.errorData.statusCode} expression is used to display the status code of the exception. Table 2-5 displays the other possible pieces of information that can be gleaned from the pageContext object. ChaPTEr 2 ■ JavaSErvEr PagES 94 Providing user-friendly error pages in any application can help create a more usable and overall more functional experience for the end user. JSP and Java technology provide robust exception handling and mechanisms that can be used to help users and administrators alike when exceptions occur. 2-14. Disabling Scriptlets in Pages Problem You want to ensure that Java code cannot be embedded into JSP pages within your web application. Solution Set the scripting-invalid element within the web deployment descriptor to true. The following excerpt from a web. xml deployment descriptor demonstrates how to do so: true How It Works When working in an environment that encourages the use of the Model-View-Controller architecture, it can be useful to prohibit the use of scriptlets within JSP pages and documents. When JSP 2.1 was released, it provided solutions to help developers move Java code out of JSP pages and into server-side Java classes where it belonged. In the early years of JSP, pages were cluttered with scriptlets and markup. This made it difficult for developers to separate business logic from content, and it was hard to find good tools to help develop such pages effectively. JSP 2.1 introduced tags, which make it possible to eliminate the use of scriptlets within JSP pages, and this helps maintain the use of the MVC architecture. Table 2-5. pageContext Implicit Object Exception Information Expression Value pageContext.errorData Provides access to the error information pageContext.exception Returns the current value of the exception object pageContext.errorData.requestURI Returns the request URI pageContext.errorData.servletName Returns the name of the servlet invoked pageContext.errorData.statusCode Returns the error status code pageContext.errorData.throwable Returns the throwable that caused the error Chapter 2 ■ JavaServer Pages 95 To prohibit the use of scriptlets within JSP pages in an application, add the jsp-config element within the web. xml file of the application of which you want to enforce the rule. Add a subelement of jsp-property-group along with the scripting-invalid element. The value of the scripting-invalid element should be set to true. 2-15. Ignoring EL in Pages Problem You want to turn off EL expression translation within your JSP page so that older applications will be able to pass through expressions verbatim. Solution #1 Escape the EL expressions within the page by using the \ character before any expressions. For instance, the following expressions will be ignored because the \ character appears before them:   \${elBean.myProperty} \${2 + 4}  Solution #2 Configure a JSP property group within the web.xml file for the application. Within the web.xml file, a element can contain child elements that characterize how the JSP page evaluates specified items. By including an true element, all EL within the application's JSP documents will be ignored and treated as literals. The following excerpt from web.xml demonstrates this feature: true Solution #3 Include a page directive including the isELIgnored attribute, and set it to true. The following page directive can be placed at the top of a given JSP document to allow each EL expression to be treated as a literal:     or in a standard JSP:   <%@ page isELIgnored="true" %>  Chapter 2 ■ JavaServer Pages 96 How It Works There may be a situation in which the evaluation of JSP EL expressions should be turned off. This occurs most often in cases of legacy applications using older versions of JSP technology; EL expressions were not yet available. There are a few different ways to turn off the evaluation of EL expressions, and this recipe demonstrates each of them. In the first solution to this recipe, the escape technique is demonstrated. An EL expression can be escaped by placing the \ character directly before the expression, as shown in the example. Doing so will cause the JSP interpreter to treat the expression as a string literal, and the output on the page will be the expression itself, rather than its evaluation. The second solution to this recipe demonstrates adding a jsp-property-group to the web.xml deployment descriptor in order to ignore EL. All EL within an application will be ignored by including the isELIgnored element and providing a true value for it. Lastly, the final solution demonstrates how to ignore EL on a page-by-page basis by including a page directive with the isELIgnored attribute set to true. Each of the different solutions for ignoring EL allows coverage to different parts of the application. The solution you choose should depend upon how broadly you want to ignore EL throughout an application. 97 Chapter 3 The Basics of JavaServer Faces In 2004 Sun Microsystems introduced a Java web framework called JavaServer Faces (JSF) in an effort to help simplify web application development. It is an evolution of the JavaServer Pages (JSP) framework, adding a more organized development life cycle and the ability to more easily utilize modern web technologies. JSF uses XML files for view construction and Java classes for application logic, making it adhere to the MVC architecture. JSF is request-driven, and each request is processed by a special servlet named the FacesServlet. The FacesServlet is responsible for building the component trees, processing events, determining which view to process next, and rendering the response. JSF 1.x used a special resource file named the faces-config.xml file for specifying application details such as navigation rules, registering listeners, and so on. While the faces-config.xml file can still be used in JSF 2.x, the more modern releases of JSF have focused on being easy to use, minimizing the amount of XML configuration, and utilizing annotations in place of XML where possible. The framework is very powerful, including easy integration with technologies such as Ajax and making it effortless to develop dynamic content. JSF works well with databases, using either JDBC or EJB technology to work with the back end. JavaBeans, known as JSF managed beans, are used for application logic and support the dynamic content within each view. They can adhere to different life spans depending upon the scope that is used. Views can invoke methods within the beans to perform actions such as data manipulation and form processing. Properties can also be declared within the beans and exposed within the views, providing a convenient way to pass request values. JSF allows developers to customize their applications with preexisting validation and conversion tags that can be used on components with the view. It is also easy to build custom validators, as well as custom components, that can be applied to components in a view. This chapter includes recipes that will be useful for those who are getting started with JSF and also those who are looking to beef up their basic knowledge of the framework. You will learn how to create managed beans, work with standard components, and handle page navigation. There are also recipes that cover useful techniques such as building custom validators and creating bookmarkable URLs. The recipes are refined to include the most current techniques and provide the most useful methodologies for using them. After studying the recipes in this chapter, you will be ready to build standard JSF applications, sprinkling in some custom features as well. Note■■   Many people prefer to work within an integrated development environment (IDE) for increased productivity. To get started with learning how to create a new JSF project and manage it with the NetBeans IDE, please see the appendix of this book. 3-1. Writing a Simple JSF Application Problem You want to get up and running quickly by creating a simple JSF application. Chapter 3 ■ The Basics of JavaServer Faces 98 Solution #1 Create a simple JSF web application that is comprised of a single XHTML page and a single JSF managed bean, along with the other required JSF configuration files. The application in this recipe simply displays a message that is initialized within a JSF managed bean. Note■■   It is recommended that you utilize a Java IDE to make life easier. If you have not yet created a JSF application and are interested in learning how to create one from scratch with an IDE, then please see Solution #2 to this recipe. This book features the NetBeans IDE, a cutting-edge Java development environment that is usually the first to support new Java features. However, there are many excellent IDE choices. You can choose the IDE you want and follow along with its instructions for working with JSF. Displaying a JSF Managed Bean Field Value The following code makes up the XHTML view that will be used to display the JSF managed bean field value:   Recipe 3-1: A Simple JSF Application

This simple application utilizes a request-scoped JSF managed bean to display the message below. If you change the "hello" variable value within the managed bean's constructor and then recompile and run the application, the new message appears.

#{helloWorldController.hello}
or

  Chapter 3 ■ The Basics of JavaServer Faces 99 As you can see, the JSF page utilizes a JSF expression, #{helloWorldController.hello}. Much like JSP technology, a backing JavaBean, otherwise known as a JSF managed bean, is referenced in the expression along with the field to expose. Examining the JSF Managed Bean The following code is that of HelloWorldController, the JSF managed bean for this recipe example:   import java.io.Serializable; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped;   /** * Recipe 3-1: A Simple JSF Application * @author juneau */ @ManagedBean(name = "helloWorldController") @RequestScoped public class HelloWorldController implements Serializable { private String hello;   /** * Creates a new instance of HelloWorldController */ public HelloWorldController() { hello = "Hello World"; }   /** * @return the hello */ public String getHello() { return hello; }   /** * @param hello the hello to set */ public void setHello(String hello) { this.hello = hello; } }   Note■■ prior to JSF 2.0, in order to enable the JSF servlet to translate the XHTML page, you needed to ensure that the web.xml file contained a servlet element indicating the javax.faces.webapp.FacesServlet class and its associated servlet-mapping URL. Since the release of JSF 2.0, if using a Servlet 3.x container, the FacesServlet is automatically mapped for you, so there is no requirement to adjust the web.xml configuration. Chapter 3 ■ The Basics of JavaServer Faces 100 Ensuring the JSF Application Functions Properly in a Pre-JSF 2.0 Environment The listing that follows is an excerpt taken from the web.xml file for the sources to this book, and it demonstrates the features that must be added to the web.xml file in order to make the JSF application function properly.   ... Faces Servlet javax.faces.webapp.FacesServlet 1 ... Faces Servlet /faces/* ... faces/index.xhtml   Let’s take a deeper look at the web.xml configuration for a JSF application. It is not very complex, but a few elements could use some explanation. The javax.faces.webapp.FacesServlet servlet must be declared within the web.xml file. The declaration must contain a servlet-name; the servlet-class element, which lists the fully qualified class name; and a load-on-startup value of 1 to ensure that the servlet is loaded when the application is started up by the container. The web.xml file must then map that servlet to a given URL within a servlet-mapping element. The servlet-mapping element must include the servlet-name, which is the same value as the servlet-name element that is contained in the servlet declaration, and a url-pattern element, which specifies the URL that will be used to map JSF pages with the servlet. When a URL is specified that contains the /faces/ mapping, the FacesServlet will be used to translate the view. To load the application in your browser, visit http://localhost:8080/JavaEERecipes/faces/chapter03/ recipe03_01.xhtml, and you will see the following text: This simple application utilizes a request-scoped JSF managed bean to display the message below. If you change the “hello” variable within the managed bean’s constructor and then recompile and run the application, the new message appears.   Hello World or Hello World  Solution #2 Use an IDE, such as NetBeans, to create a JSF application. To get started with NetBeans, first download the most recent release of NetBeans from the Netbeans.org web site. The examples in this solution make use of NetBeans 7.3. For more information about downloading and installing NetBeans, please see the appendix to this book. Once installed, create a new project by clicking the File ➤ New Project menu option. Follow the directions in the book’s appendix (in the “Creating a NetBeans Java Web Project” section). Once completed, the index.xhtml file will open in the editor, which will be the default landing page for your application. Modify the index.xhtml file by making the page the same as the JSF view that is listed in Solution #1’s “Displaying JSF Managed Bean Field Value” section. Once done, add the managed bean to your application that will be used to supply Chapter 3 ■ The Basics of JavaServer Faces 101 the business logic for the index.xhtml page. To create the managed bean, right-click the Source Packages navigation menu for your project, and choose New ➤ JSF Managed Bean from the context menu. This will open the New JSF Managed Bean dialog (Figure 3-1), which will allow you to specify several options for your managed bean, including the name, location, and scope. Figure 3-1.  New JSF managed bean For the purposes of this recipe, change the name of the bean to HelloWorldController, and leave the rest of the options at their defaults; then click Finish. Copy and paste the code from Solution #1’s “Examining the JSF Managed Bean” section into the newly created managed bean class. Once finished, right-click the application project from the Project navigation menu and choose Deploy to deploy your application. To load the application in your browser, visit http://localhost:8080/WebApplication1/faces/index.xhtml, and you will see the following text: This simple application utilizes a request-scoped JSF managed bean to display the message below. If you change the “hello” variable within the managed bean’s constructor and then recompile and run the application, the new message appears.   Hello World or Hello World   Chapter 3 ■ The Basics of JavaServer Faces 102 How It Works This recipe merely scratches the surface of JSF, but it is meant as a starting point to guide you along the path of becoming a JSF expert. The example in this recipe demonstrates how closely related JSF and JSP technologies are. In fact, the only difference in the two view pages is the use of the JSF expression #{} rather than the standard JSP value expression ${}. Thanks to the JSP 2.0 unified expression language, Java web developers now have an easy transition between the two technologies, and they now share many of the same expression language features. Note■■   JSF 2.x can make use of Facelets view technology to produce even more sophisticated and organized designs. To learn more about Facelets view technology, please refer to Chapter 4. Breaking Down a JSF Application Now for the real reason you are reading this recipe…the explanation for building a JSF application! A JSF application is comprised of the following parts: If using or maintaining JSF applications written using JSF 1.• x, the web.xml deployment descriptor that is responsible for mapping the FacesServlet instance to a URL path One or more web pages on which JSF components are used to provide the page layout (may or • may not utilize Facelets view technology) JSF component tags• One or more managed beans, which are simple, lightweight container-managed objects that • are responsible for supporting page constructs and basic services Optionally, one or more configuration files such as • faces-config.xml that can be used to define navigation rules and configure beans and other custom objects Optionally, supporting objects such as listeners, converters, or custom component• Optionally, custom tags for use on a JSF view• Life Cycle of a JSF Application The JSF view processing life cycle contains six stages. These stages are as follows: 1. restore View 2. apply Request Values 3. process Validations 4. Update Model Values 5. Invoke Application 6. render Response Restore View is the first phase in the JSF life cycle, and it is responsible for constructing the view. The component tree then applies the request parameters to each of the corresponding component values using the component Chapter 3 ■ The Basics of JavaServer Faces 103 tree’s decode method. This occurs during the Apply Request Values phase. During this phase, any value conversion errors will be added to FacesContext for display as error messages during the Render Response phase. Next, all of the validations are processed. During the Process Validations phase, each component that has a registered validator is examined, and local values are compared to the validation rules. If any validation errors arise, the Render Response phase is entered, rendering the page with the corresponding validation errors. If the Process Validations phase exits without errors, the Update Model Values phase begins. During this phase, managed bean properties are set for each of the corresponding input components within the tree that contain local values. Once again, if any errors occur, then the Render Response phase is entered, rendering the page with the corresponding errors displayed. After the successful completion of the Update Model Values phase, the application-level events are handled during the Invoke Applications phase. Such events include page submits or redirects to other pages. Finally, the Render Response phase occurs, and the page is rendered to the user. If the application is using JSP pages, then the JSF implementation allows the JSP container to render the page. The example in this recipe uses the minimum number of these parts. To run the example, you will need to ensure that the web.xml file contains the proper JSF configuration if running in a pre-JSF 2.x environment. You will need to have a managed bean declaring the field that is exposed on the JSF view along with the necessary accessor methods to make it work properly. And lastly, you will need to have the XHTML JSF view page containing the JSF expression that exposes the field that is declared within the managed bean. A JSF managed bean is a lightweight, container-managed object that is associated with a JSF page. The managed bean is much like a JSP JavaBean in that it provides the application logic for a particular page so that Java code does not need to be embedded into the view code. Components (a.k.a. JSF tags) that are used within a JSF view are mapped to server-side fields and methods contained within the JSF managed bean. Oftentimes, JSF managed beans contain Controller within their name because they are indeed the controllers for the page logic. In the example, the JSF managed bean is named HelloWorldController, and a field named hello is declared, exposing itself to the public via the getHello and setHello methods. The JSF managed bean is instantiated and initialized when a page that contains a reference to the bean is requested, and the managed bean scope determines the life span of the bean. In the case of this example, the managed bean contains a request scope, via the @RequestScoped annotation. Therefore, its life span is that of a single request, and it is re-instantiated each time the page in the example is reloaded. To learn more about the scope and annotations that are available for a managed bean, please see Recipe 3-2. JSF technology utilizes a web view declaration framework known as Facelets. Facelets uses a special set of XML tags, similar in style to the standard JSF tags, to help build componentized web views. To learn more about Facelets, please see Chapter 4. While this example does not use Facelets, it is a vital part of JSF view technology. Facelets pages typically use XHTML, which is an HTML page that is comprised of well-formed XML components. The example JSF view in this recipe is well-structured, and it contains two JSF EL expressions that are responsible for instantiating the managed bean and displaying the content for the hello field. When the EL expression #{helloWorldBean.hello} is translated by the FacesServlet, it makes the call to the HelloBeanController’s getHello() method. Lots of information was thrown at you within this introductory recipe. The simple example in this recipe provides a good starting point for working with JSF technology. Continue with the recipes in this chapter to gain a broader knowledge of each component that is used for developing JavaServer Faces web applications. 3-2. Writing a Managed Bean Problem You want to use a server-side Java class from within your JSF application web pages. ChapTEr 3 ■ ThE BaSICS oF JavaSErvEr FaCES 104 Solution Develop a JSF managed bean, a lightweight container-managed component, which will provide the application logic for use within your JSF application web pages. The example in this recipe is comprised of a JSF view and a JSF managed bean. The application calculates two numbers that are entered by the user and then adds, subtracts, multiplies, or divides them depending upon the user’s selection. The following code is the managed bean that is responsible for declaring fields for each of the numbers that will be entered by the user, as well as a field for the result of the calculation. The managed bean is also responsible for creating a list of Strings that will be displayed within an h:selectOneMenu element within the JSF view and retaining the value that is chosen by the user. Although it may seem as though this managed bean is doing a lot of work, it actually is very simple to make it happen! The managed bean is really a beefed-up Plain Old Java Object (POJO) that includes some methods that can be called from JSF view components. Managed Bean The following code is for the managed bean that is used for the calculation example. The bean is named CalculationController, and it is referenced as calculationController from within the JSF view. JSF uses convention over configuration for its naming conventions. By default, JSF views can contain EL that references a managed bean by specifying the class name with the first character in lowercase. package org.javaeerecipes.chapter03.recipe03_02; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.faces.bean.ManagedBean; import javax.faces.application.FacesMessage; import javax.faces.bean.SessionScoped; import javax.faces.context.FacesContext; import javax.faces.model.SelectItem; /** * Recipe 3-2: Writing a JSF Managed Bean * @author juneau */ @SessionScoped @ManagedBean(name="calculationController") public class CalculationController implements Serializable { private int num1; private int num2; private int result; private String calculationType; private static String ADDITION = "Addition"; private static String SUBTRACTION = "Subtraction"; private static String MULTIPLICATION = "Multiplication"; private static String DIVISION = "Division"; List calculationList; Chapter 3 ■ The Basics of JavaServer Faces 105 /** * Creates a new instance of CalculationController */ public CalculationController() { // Initialize variables num1 = 0; num2 = 0; result = 0; calculationType = null; // Initialize the list of values for the SelectOneMenu populateCalculationList(); }   /** * @return the num1 */ public int getNum1() { return num1; }   /** * @param num1 the num1 to set */ public void setNum1(int num1) { this.num1 = num1; }   /** * @return the num2 */ public int getNum2() { return num2; }   /** * @param num2 the num2 to set */ public void setNum2(int num2) { this.num2 = num2; }   /** * @return the result */ public int getResult() { return result; }   /** * @param result the result to set */ Chapter 3 ■ The Basics of JavaServer Faces 106 public void setResult(int result) { this.result = result; }   /** * @return the calculationType */ public String getCalculationType() { return calculationType; }   /** * @param calculationType the calculationType to set */ public void setCalculationType(String calculationType) { this.calculationType = calculationType; }   public List getCalculationList(){ return calculationList; }   private void populateCalculationList(){ calculationList = new ArrayList(); calculationList.add(new SelectItem(ADDITION)); calculationList.add(new SelectItem(SUBTRACTION)); calculationList.add(new SelectItem(MULTIPLICATION)); calculationList.add(new SelectItem(DIVISION)); }   public void performCalculation() { if (getCalculationType().equals(ADDITION)){ setResult(num1 + num2); } else if (getCalculationType().equals(SUBTRACTION)){ setResult(num1 - num2); } else if (getCalculationType().equals(MULTIPLICATION)){ setResult(num1 * num2); } else if (getCalculationType().equals(DIVISION)){ try{ setResult(num1 / num2); } catch (Exception ex){ FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid Calculation", "Invalid Calculation"); FacesContext.getCurrentInstance().addMessage(null, facesMsg); } } } }   Next is the view that composes the web page, which is displayed to the user. The view is composed within an XHTML document and is well-formed XML. Chapter 3 ■ The Basics of JavaServer Faces 107 JSF View The view contains JSF components that are displayed as text boxes into which the user can enter information, a pick-list of different calculation types for the user to choose from, a component responsible for displaying the result of the calculation, and an h:commandButton component for submitting the form values.   Recipe 3-2: Writing a JSF Managed Bean

Perform a Calculation

Use the following form to perform a calculation on two numbers.
Enter the numbers in the two text fields below, and select a calculation to
perform, then hit the "Calculate" button.


Number1:
Number2:

Calculation Type:

Result: Chapter 3 ■ The Basics of JavaServer Faces 108

  The resulting JSF view looks like Figure 3-2 when displayed to the user. Figure 3-2.  Resulting JSF view page How It Works The JSF managed bean is responsible for providing the application logic for a JSF-based web application. Much like the JavaBean is to a JSP, the managed bean is the backbone for a JSF view. They are also referred to as backing beans, because there is typically one JSF managed bean per each JSF view. Managed beans have changed a bit since the JSF technology was first introduced. There used to be configuration required for each managed bean within a faces-config.xml configuration file and also within the web.xml file for use with some application servers. Starting with the release of JSF 2.0, managed beans became easier to use, and coding powerful JSF applications is easier than ever. This recipe focuses on newer managed bean technology. The example for this recipe demonstrates many of the most important features of a JSF managed bean. The view components refer to the managed bean as calculationController. By default, a JSF managed bean can be referred to within a JSF view using the name of the bean class with a lowercase first letter. However, using the @ManagedBean annotation, the string that is used to reference the bean from within a view can be changed. In the example, calculationController is also used as the name passed to the @ManagedBean annotation, but it could have easily been some other string. The @ManagedBean annotation should be placed before the class declaration.   @ManagedBean(name = "calculationController")   Chapter 3 ■ The Basics of JavaServer Faces 109 Scopes The bean in the example will be initialized when it is first accessed by a session and destroyed when the session is destroyed. It is a managed bean that “lives” with the session. The scope of the bean is configured by an annotation on the class, just before the class declaration. There are different annotations that can be used for each available scope. In this case, the annotation is @SessionScoped, denoting that the managed bean is session-scoped. All of the possible managed bean scopes are listed within Table 3-1. Table 3-1.  Managed Bean Scopes Scope Annotation Description @ApplicationScoped Specifies that a bean is application scoped. Initialized when the application is started up. Destroyed when the application is shut down. Managed beans with this scope are available to all application constructs in the same application throughout the life of a session. @ConversationScoped Specifies that a bean is conversation scoped. Initialized when a conversation is started and destroyed when the conversation ends. Managed beans with this scope are available throughout the life cycle of a conversation, and belong to a single HTTP session. If the HTTP session ends, all conversation contexts that were created during the session are destroyed. @CustomScoped Specifies that the runtime must act as if a VALUE element was declared for the corresponding managed bean, where VALUE is the value of the value() attribute, which must be an EL expression that evaluates to a String. This allows the scope to be customized depending upon code-based values. @Dependent Specifies that a bean belongs to a dependent pseudo-scope. Beans that use this scope behave differently than managed beans containing any of the other scopes. To learn more about using this scope, please see Recipe 6-20. @NoneScoped Specifies that the runtime must act as if a none element was declared for the corresponding managed bean. This implies that there is no scope for the managed bean. This causes the bean to be instantiated each time it is referenced. This is useful in situations where beans reference each other and the referenced bean should not maintain a state. @RequestScoped Specifies that a bean is request scoped. Initialized when a request to the bean is made and destroyed when the request is complete. @SessionScoped Specifies that a bean is session scoped. Initialized when first accessed within a session. Destroyed when the session ends. Available to all servlet requests that are made within the same session. @ViewScoped Specifies that the runtime must act as if a view element was declared for the corresponding managed bean. In this case, the scope persists for a single web page (view) of an application within a user session. The @ManagedBean annotation specifies to the application server container that the class is a JSF managed bean. Prior to JSF 2.0, a managed bean had to be declared within the faces-config.xml file. The addition of annotations has made JSF managed beans XML configuration-free. It is important to note that the managed bean implements java.io.Serializable; all managed beans should be specified as serializable so that they can be persisted to disk by the container if necessary. Chapter 3 ■ The Basics of JavaServer Faces 110 Fields declared within a managed bean should be specified as private in order to adhere to object-oriented methodology. To make a field accessible to the public and usable from JSF views, accessor methods should be declared for it. Any field that has a corresponding “getter” and “setter” is known as a JSF managed bean property. Properties are available for use within JSF views by utilizing lvalue JSF EL expressions, meaning that the expression is contained within the #{ and } character sequences and that it is readable and writable. For instance, to access the field num1 that is declared within the managed bean, the JSF view can use the #{calculationController.num1} expression, as you can see in the JSF view code for the example. Any pubic method contained within a JSF managed bean is accessible from within a JSF view using the same EL expression syntax, that is, by specifying #{beanName.methodName} as the expression. In the example to this recipe, the performCalculation method of the managed bean is invoked from within the JSF view using an h:commandButton JSF component. The component action is equal to the EL expression that will invoke the JSF managed bean method. To learn more about JSF components and how to use them in view, please see Recipe 3-3 and Chapter 5.     Note■■   The input form for this example contains no action attribute. JSF forms do not contain action attributes since JSF components within the view are responsible for specifying the action method, rather than the form itself. JSF managed beans are a fundamental part of the JSF web framework. They provide the means for developing dynamic, robust, and sophisticated web applications with the Java platform. 3-3. Building Sophisticated JSF Views with Components Problem You want to create a sophisticated user interface comprised of prebundled components. Solution Make use of bundled JSF components within your JSF views. JSF components contain bundled application logic and view constructs that can be used within applications by merely adding tags to a view. In the following example, several JSF components are used to create a view that displays the authors for an Apress book and allows for a new author to be added to the list. The following code is the XHTML for the JSF view:   Chapter 3 ■ The Basics of JavaServer Faces 111 Recipe 3-3: Building Sophisticated JSF Views with Components

JSF Components, Creating a Sophisticated Page

The view for this page is made up entirely of JSF standard components.
As you can see, there are many useful components bundled with JSF out of the box.

Book Recommendation: Java 7 Recipes

Use the following form to add an author to the list.








Java 7 Recipes Authors

  Chapter 3 ■ The Basics of JavaServer Faces 112 This example utilizes a JSF managed bean named AuthorController. The managed bean declares a handful of properties that are exposed in the view, and it also declares and populates a list of authors that is displayed on the page within a JSF h:dataTable component.   package org.javaeerecipes.chapter03.recipe03_03;   import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; import javax.inject.Named;   /** * Recipe 3-3 * @author juneau */ @ManagedBean(name = "authorController") @SessionScoped public class AuthorController implements Serializable {   private String newAuthorFirst; private String newAuthorLast; private String bio; private List authorList;   /** * Creates a new instance of RecipeController */ public AuthorController() { populateAuthorList(); }   private void populateAuthorList(){ System.out.println("initializng authors"); authorList = new ArrayList<>(); authorList.add(new Author("Josh", "Juneau", null)); authorList.add(new Author("Carl", "Dea", null)); authorList.add(new Author("Mark", "Beaty", null)); authorList.add(new Author("John", "O'Conner", null)); authorList.add(new Author("Freddy", "Guime", null));     }   public void addAuthor() { getAuthorList().add( new Author(this.getNewAuthorFirst(), this.getNewAuthorLast(), this.getBio())); }   Chapter 3 ■ The Basics of JavaServer Faces 113 /** * @return the authorList */ public List getAuthorList() { return authorList; }   /** * @param authorList the authorList to set */ public void setAuthorList(List authorList) { this.authorList = authorList; }   /** * @return the newAuthorFirst */ public String getNewAuthorFirst() { return newAuthorFirst; }   /** * @param newAuthorFirst the newAuthorFirst to set */ public void setNewAuthorFirst(String newAuthorFirst) { this.newAuthorFirst = newAuthorFirst; }   /** * @return the newAuthorLast */ public String getNewAuthorLast() { return newAuthorLast; }   /** * @param newAuthorLast the newAuthorLast to set */ public void setNewAuthorLast(String newAuthorLast) { this.newAuthorLast = newAuthorLast; }   /** * @return the bio */ public String getBio() { return bio; }   ChapTEr 3 ■ ThE BaSICS oF JavaSErvEr FaCES 114 /** * @param bio the bio to set */ public void setBio(String bio) { this.bio = bio; } } Finally, the Author class is used to hold instances of Author objects that are loaded into the authorList. The following code is for the Author class: package org.javaeerecipes.chapter03.recipe03_03; /** * Recipe 3-3 * @author juneau */ public class Author implements java.io.Serializable { private String first; private String last; private String bio; public Author(){ this.first = null; this.last = null; this.bio = null; } public Author(String first, String last, String bio){ this.first = first; this.last = last; this.bio = bio; } /** * @return the first */ public String getFirst() { return first; } /** * @param first the first to set */ public void setFirst(String first) { this.first = first; } /** * @return the last */ Chapter 3 ■ The Basics of JavaServer Faces 115 public String getLast() { return last; }   /** * @param last the last to set */ public void setLast(String last) { this.last = last; }   /** * @return the bio */ public String getBio() { return bio; }   /** * @param bio the bio to set */ public void setBio(String bio) { this.bio = bio; } }   The resulting web page would resemble the page shown in Figure 3-3. Chapter 3 ■ The Basics of JavaServer Faces 116 How It Works JSF views are comprised of well-formed XML, being a mixture of HTML and JSF component tags. Any well-formed HTML can be used within a JSF view, but the components are the means by which JSF communicates with managed bean instances. There are components shipped with JSF that can be used for adding images to views, text areas, buttons, checkboxes, and much more. Moreover, there are several very good component libraries that include additional JSF components, which can be used within your applications. This recipe is meant to give you an overall understanding of JSF components and how they work. You can learn more details regarding JSF components and the use of external component libraries by reading the recipes in Chapter 5. Figure 3-3.  Sophisticated JSF view example Chapter 3 ■ The Basics of JavaServer Faces 117 The first step toward using a component within a JSF view is to declare the tag library on the page. This is done within the HTML element at the top of the page. The example in this recipe declares both the JSF core component library and the JSF HTML component library within the HTML element near the top of the page. These two libraries are standard JSF component libraries that should be declared in every JSF view.   ... ...   Once a library is declared, a component from within that library can be used in the view by specifying the library namespace, along with the component you want to use. For instance, to specify an HTML element for displaying text, use the JSF h:outputText component tag, along with the various component attributes. Prior to JSF 2.0, it was important to enclose a JSF view along with all of the components within the f:view tag. As of JSF 2.0, the tag is no longer required because the underlying Facelets view technology is part of every JSF view by default, so it takes care of specifying the view automatically. However, the f:view element can still be useful for specifying locale, content type, or encoding. Please see the online documentation for more information regarding the use of those features: http://docs.oracle.com/cd/E17802_01/j2ee/javaee/javaserverfaces/2.0/docs/pdldocs/ facelets/index.html. The and tags can be used to specify the header and body for a JSF web view. However, using the standard HTML and tags is fine also. Some Java IDEs will automatically use and in place of the standard HTML tags when writing JSF views. An important note is that you must enclose any content that will be treated as an HTML input form with the JSF tag. This tag encloses a JSF form and renders an HTML form using a POST method if none is specified. No action attribute is required for a JSF form tag because the JSF managed bean action is invoked using one of the JSF action components such as h:commandButton or h:commandLink. Tip■■ always specify an id for the h:form tag because the form id is added as a prefix to all JSF component tag ids when the page is rendered. For instance, if a form id of myform contained a component tag with an id of mytag, the component id will be rendered as myform:mytag. If you do not specify an id, then one will be generated for you automatically. If you want to use JavaScript to work with any of the page components, you will need to have an id specified for h:form, or you will never be able to access them. Note■■   This recipe provides a quick overview of a handful of the standard JSF components. For an in-depth explanation of JSF components and their usage, please see Chapter 5. The standard JSF component library contains a variety of components, and a few of them are utilized in the example. The h:graphicImage tag can be used to place an image on the page and utilize a JSF managed bean if needed. The h:graphicImage tag is rendered into an HTML component, and as with all of the other JSF components, it accepts JSF EL expressions within its attributes, which allows for the rendering of dynamic images. In this recipe, a static image is specified with the url attribute, but an expression could also be used, making use of a JSF managed bean field. The library attribute is used to specify the directory in which the resource, in this case an image, resides.     The h:outputLabel tag is useful for reading managed bean properties and displaying their values when the view is rendered. They are rendered as a label for a corresponding field within the view. The example utilizes static values for the h:outputLabel component, but they could include JSF expressions if needed. The h:outputText component Chapter 3 ■ The Basics of JavaServer Faces 118 is also useful for reading managed bean properties and displaying their values. This component renders basic text on the page. The difference between h:outputLabel and h:outputText is that they are rendered into different HTML tags. Both components can accept JSF managed bean expressions for their value attributes. In the example, a couple of text fields are displayed on the page using the h:inputText component, which renders an input field. The value attribute for h:inputText can be set to a JSF managed bean field, which binds the text field to the corresponding managed bean property. For instance, the example includes an h:inputText component with a value of #{authorController.newAuthorFirst}, which binds the component to the newAuthorFirst property within the AuthorController class. If the field contains a value, then a value will be present within a text field when the page is rendered. If a value is entered into the corresponding text field and the form is submitted, the value will be set into the newAuthorFirst field using its setter method. The h:inputText tag allows for both reading and writing of managed bean properties because it uses lvalue JSF EL expressions. The h:inputTextarea tag is very similar to h:inputText in that it works the same way, but it renders a text area rather than a text field. The h:commandButton component is used to render a submit button on a page. Its action attribute can be set to a JSF managed bean method. When the button is pressed, the corresponding managed bean method will be executed, and the form will be submitted. The request will be sent to the FacesServlet controller, and any properties on the page will be set. Please see Recipe 3-1 for more details regarding the JSF life cycle. The h:commandButton used in the example has an action attribute of #{authorController.addAuthor}, which will invoke the addAuthor method within the AuthorController managed bean. As you can see from the method, when invoked it will add a new Author object to the authorList, utilizing the values that were populated within the corresponding h:inputText components for the newAuthorFirst, newAuthorLast, and bio fields. The following excerpt from the example’s JSF view lists the h:commandButton component:     The last component in the example that bears some explanation is the h:dataTable. This JSF component is rendered into an HTML table, and it enables developers to dynamically populate tables with collections of data from a managed bean. In the example, the h:dataTable value attribute is set to the managed bean property of #{authorController.authorList}, which maps to an instance of ArrayList that is populated with Author objects. The dataTable var attribute contains a String that will be used to reference the different objects contained within each row of the table. In the example, the var attribute is set to author, so referencing #{author.first} within the dataTable will return the value for the current Author object’s first property. The dataTable in the example effectively prints out the first and last names of each Author object within the authorList. This is just a quick overview of how the JSF dataTable component works. For more details, please refer to Recipe 3-12. As you work more with constructing JSF views, you will become very familiar with the component library. The tags will become second nature, and you will be able to construct highly sophisticated views for your application. Adding external JSF component libraries into the mix along with using Ajax for updating components is the real icing on the cake! You will learn more about spreading the icing on the cake and creating beautiful and user-friendly views in Chapter 5! 3-4. Displaying Messages in JSF Pages Problem You have the requirement to display an information message on the screen for your application users. Solution Add the h:messages component to your JSF view and create messages as needed within the view’s managed bean using FacesMessage objects. The following JSF view contains an h:messages component tag that will render any messages that were registered with FacesContext within the corresponding page’s managed bean. It also includes an Chapter 3 ■ The Basics of JavaServer Faces 119 h:message component that is bound to an h:inputText field. The h:message component can display messages that are specific to the corresponding text field.   Recipe 3-4: Displaying Messages in JSF Pages

JSF Messages

This page contains a JSF message component below. It will display messages from a JSF managed bean once the bean has been initialized.



Enter the word Java here:

  The managed bean in this example is named MessageController. It will create a JSF message upon initialization, and then each time the newMessage method is invoked, another message will be displayed. Also, if the text java is entered into the text field that corresponds to the h:inputText tag, then a success message will be displayed for that component. Otherwise, if a different value is entered into that field or if the field is left blank, then an error message will be displayed. The following listing is that of MessageController:   package org.javaeerecipes.chapter03.recipe03_04;   import java.util.Date; import javax.annotation.ManagedBean; import javax.faces.bean.SessionScoped; import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext; Chapter 3 ■ The Basics of JavaServer Faces 120 /** * Recipe 3-4 * @author juneau */ @SessionScoped @ManagedBean public class MessageController implements java.io.Serializable { int hitCounter = 0; private String javaText;   /** * Creates a new instance of MessageController */ public MessageController() { javaText = null; FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Managed Bean Initialized", null);   FacesContext.getCurrentInstance().addMessage(null, facesMsg); }   public void newMessage(){ String hitMessage = null; hitCounter++; if(hitCounter > 1){ hitMessage = hitCounter + " times"; } else { hitMessage = hitCounter + " time"; }   Date currDate = new Date(); FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "You've pressed that button " + hitMessage + "! The current date and time: " + currDate, null); FacesContext.getCurrentInstance().addMessage(null, facesMsg);   if (getJavaText().equalsIgnoreCase("java")){ FacesMessage javaTextMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Good Job, that is the correct text!", null); FacesContext.getCurrentInstance().addMessage("componentForm:javaText", javaTextMsg); } else { FacesMessage javaTextMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Sorry, that is NOT the correct text!", null); FacesContext.getCurrentInstance().addMessage("componentForm:javaText", javaTextMsg); } }   /** * @return the javaText */ Chapter 3 ■ The Basics of JavaServer Faces 121 public String getJavaText() { return javaText; }   /** * @param javaText the javaText to set */ public void setJavaText(String javaText) { this.javaText = javaText; } }   The message will be displayed on the page in red text if it is an error message and in green text if it is an informational message. In this example, the initialization message is printed green, and the update message is printed in red. How It Works It is always a good idea to relay messages to application users, especially in the event that some action needs to be taken by the user. The JSF framework provides an easy façade that allows messages to be added to a view from the JSF managed bean. To use the façade, add the h:message component to a view for displaying messages that are bound to specific components, and add the h:messages component to a view for displaying messages that are not bound to specific components. The h:message component contains a number of attributes that can be used to customize message output and other things. It can be bound to a component within the same view by specifying that component’s id in the for attribute of h:message. The most important attributes for the h:message component are as follows: • id: Specifies a unique identifier for the component • rendered: Specifies whether the message is rendered • errorStyle: Specifies the CSS styles to be applied to error messages • errorClass: Indicates the CSS class to apply to error messages • infoStyle: Specifies the CSS styles to be applied to informational messages • infoClass: Indicates the CSS class to apply to informational messages • for: Specifies the component for which the message belongs For a list of all attributes available for the h:message component, please refer to the online documentation. In the example for this recipe, the h:message component is bound to the h:inputText component with an id of javaText. When the page is submitted, the newMessage method within the MessageController class is invoked. That method is used in this example for generating messages to display on the page. If the text entered within the javaText property matches Java, then a successful message will be printed on the page. To create a message, an instance of the javax.faces.application.FacesMessage class is generated, passing three parameters that correspond to message severity, message summary, and message detail. A FacesMessage object can be created without passing any parameters, but usually it is more productive to pass the message into the constructor at the time of instantiation. The general format for creating a FacesMessage object is as follows:   new FacesMessage(FacesMessage.severity severity, String summary, String detail)   Passing a static field from the FacesMessage class specifies the message severity. Table 3-2 shows the possible message severity values along with their descriptions. Chapter 3 ■ The Basics of JavaServer Faces 122 In the example, if the value entered for the javaText property equals Java, then an informational message is created. Otherwise, an error message is created. In either case, once the message is created, then it needs to be passed into the current context using FacesContext.getCurrentInstance().addMessage(String componentId, FacesMessage message). In the example, the method is called, passing a component ID of componentForm:javaText. This refers to the component within the JSF view that has an ID of javaText (h:inputText component). The componentForm identifier belongs to the form (h:form component) that contains the h:inputText component, so in reality the h:inputText component is nested within the h:form component. To reference a nested component, combine component IDs using a colon as a delimiter. The following is an excerpt from the example, demonstrating how to create a message and send it to the h:message component:   FacesMessage javaTextMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Sorry, that is NOT the correct text!", null); FacesContext.getCurrentInstance().addMessage("componentForm:javaText", javaTextMsg);   The h:messages component can be used for displaying all messages that pertain to a view, or it can be used for displaying only non-component-related messages by using the globalOnly attribute. All other attributes for h:messages are very similar to the h:message component. By indicating a true value for the globalOnly attribute, you are telling the component to ignore any component-specific messages. Therefore, any FacesMessage that is sent to a specific component will not be displayed by h:messages. In the example, the message that is displayed by h:messages is generated in the same manner as the component-specific message, with the exception of specifying a specific component to which the message belongs. The following excerpt demonstrates sending an error message to the h:messages component. Note that the last argument that is sent to the FacesMessage call is a null value. This argument should be the clientId specification, and by setting it to null, you are indicating that there is no specified client identifier. Therefore, the message should be a global message rather than tied to a specific component.   FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "You've pressed that button " + hitMessage + "! The current date and time: " + currDate, null); FacesContext.getCurrentInstance().addMessage(null, facesMsg);   Displaying the appropriate message at the right time within an application is very important. By utilizing FacesMessages objects and displaying them using either the h:message or h:messages component, you can ensure that your application users will be well informed of the application state. 3-5. Navigation Based Upon Conditions Problem Your JSF application contains multiple pages, and you want to set up navigation between them. Table 3-2.  FacesMessage Severity Values Severity Description SEVERITY_ERROR Indicates that an error has occurred SEVERITY_FATAL Indicates that a serious error has occurred SEVERITY_INFO Indicates an informational message rather than an error SEVERITY_WARN Indicates that an error may have occurred Chapter 3 ■ The Basics of JavaServer Faces 123 Solution Utilize one of the following techniques for performing navigation within JSF applications: Utilize explicit navigation through the use of a JSF managed bean method along with a • corresponding faces-config.xml configuration file to control the navigation for your application. Use implicit navigation for specifying the next view to render from within the managed bean.• Use implicit navigation by specifying the name of the view to render as the • action attribute of a component tag, bypassing the managed bean altogether. The example in this recipe consists of four JSF views, and each one contains h:commandButton components that invoke navigation to another view. The h:commandButton components are linked to managed bean methods that are present within the view’s corresponding managed bean named NavigationController. The first view listed here contains two h:commandButton components, each of which invokes a method within the managed bean named NavigationController. The first button utilizes explicit JSF navigation, and the second uses implicit navigation.   Recipe 3-5

JSF Navigation - Page 1

Clicking the submit button below will take you to Page #2.




  ChapTEr 3 ■ ThE BaSICS oF JavaSErvEr FaCES 124 The source for the second JSF view is very similar, except that a different managed bean method is specified within the action attribute of the view’s h:commandButton component. Recipe 3-5: JSF Navigation

JSF Navigation - Page 2

Clicking the submit button below will take you to Page #1.


The third JSF view contains an h:commandButton component that invokes a managed bean action and utilizes conditional navigation, rendering pages depending upon a conditional outcome within the faces-config.xml. Recipe 3-5: JSF Navigation Chapter 3 ■ The Basics of JavaServer Faces 125

JSF Navigation - Page 3

The button below will utilize conditional navigation to take a user to the next page.


  Lastly, the fourth JSF view in the navigational example application contains an h:commandButton that invokes a method and uses implicit navigation to return to the third JSF view, specifying the view name within the action attribute directly and bypassing the managed bean altogether.   Recipe 3-5: JSF Navigation

JSF Navigation - Page 4

Clicking the submit button below will take you to Page #1 using conditional navigation rules.


  Now let’s take a look at the source listing for NavigationController. It contains the methods that are specified within each page’s h:commandButton action attribute. Some of the methods return a String value, and others do not. However, after the methods are invoked, then the FacesServlet processes the request, and the faces-config.xml configuration file is traversed, if needed, to determine the next view to render. Chapter 3 ■ The Basics of JavaServer Faces 126  package org.javaeerecipes.chapter03.recipe03_05;   import javax.faces.bean.Named; import javax.faces.bean.RequestScoped;   /** * Recipe 3-5 * @author juneau */ @ManagedBean(name = "navigationController") @RequestScoped public class NavigationController implements java.io.Serializable{   private boolean authenticated = false;   /** * Creates a new instance of NavigationController */ public NavigationController() { }   public String pageOne(){ return "PAGE_1; }   public String pageTwo(){ return "PAGE_2; }   /** * Utilizing implicit navigation, a page name can be returned from an * action method rather than listing a navigation-rule within faces-config.xml * @return */ public String nextPage(){ // Perform some task, then implicitly list a page to render   return "recipe03_05c"; }   /** * Demonstrates the use of conditional navigation */ public void login(){ // Perform some task and then return boolean setAuthenticated(true); System.out.println("Here"); }   /** * @return the authenticated */ Chapter 3 ■ The Basics of JavaServer Faces 127 public boolean isAuthenticated() { return authenticated; }   /** * @param authenticated the authenticated to set */ public void setAuthenticated(boolean authenticated) { this.authenticated = authenticated; } }   At the heart of the navigation is the faces-config.xml file. It specifies which view should be displayed after a corresponding outcome. Two of the navigation-rules use standard JSF navigation, and the last navigation-rule makes use of conditional navigation.   /chapter03/recipe03_05a.xhtml PAGE_2/from-outcome> /chapter03/recipe03_05b.xhtml /chapter03/recipe03_05b.xhtml PAGE_1 /chapter03/recipe03_05a.xhtml #{navigationController.login} #{navigationController.authenticated} /chapter03/recipe03_05d.xhtml   Chapter 3 ■ The Basics of JavaServer Faces 128 How It Works One of the most daunting tasks when building a web application is to determine the overall page navigation. Many web frameworks have instituted XML configuration files for organizing page navigation. This holds true for the JavaServer Faces web framework, and the navigational XML is placed within a JSF application’s faces-config.xml configuration file. When using standard navigation, JSF utilizes navigation rules to determine which view to render based upon the outcome of page actions. If using standard JSF navigation, when a page action occurs, the managed bean method that is associated with the action can return a String value. That value is then evaluated using the navigational rules that are defined within the faces-config.xml file and used to determine which page to render next. The standard navigation infrastructure works well in most cases, but in some instances it makes more sense to directly list the next page to be rendered within the managed bean, rather than making a navigation rule in the configuration file. When a managed bean action is invoked, it can return the name of a view, without the .xhtml suffix. Such navigation was introduced with the release of JSF 2.0, and it is known as implicit navigation. As shown in the fourth example for the solution, you can also perform implicit navigation by specifying the name of a view without the suffix for an action attribute of the component tag. Yet another type of navigation was introduced with JSF 2.0, taking navigation to the next level by allowing the use of JSF EL expressions within the faces-config.xml navigation rules. Conditional navigation allows for an element to be specified within the navigational rule, which corresponds to a JSF EL condition. If the condition evaluates to true, then the specified view is rendered. Navigation rules are constructed in XML residing within the faces-config.xml descriptor, and each rule has a root element of navigation-rule. Within each rule construct, the from-view-id element should contain the name of the view from which the action method was invoked. A series of navigation-cases should follow the from- view-id element. Each navigation-case contains a from-outcome element, which should be set to a String value corresponding to the String value that is returned from a subsequent action method. For instance, when the pageOne method is invoked in the example, the String "PAGE_1" is returned, and it should be specified within the from- outcome element within a navigation-case in the faces-config.xml file. Lastly, the to-view-id element should follow the from-outcome element within the navigation-case, and it should specify which view to render if the String in from-outcome is returned from the action method. The following excerpt shows the standard navigation rule that allows for navigation from page 1 to page 2 of the application:   /chapter03/recipe03_05a.xhtml PAGE_1 /chapter03/recipe03_05b.xhtml   Implicit navigation does not require any XML navigation rules to be declared. The action method that is invoked via an h:commandButton returns a String that is equal to the name of the view that should be rendered next. In the example, the second h:commandButton on view 1 invokes the nextPage managed bean method, which returns the name of the next view that should be rendered.   public String nextPage(){ // Perform some task, then implicitly list a page to render   return "recipe03_05c"; }   If you want to use implicit navigation, you can bypass the managed bean altogether and specify the name of the view that you want to render directly within the action attribute of h:commandButton or h:commandLink. The fourth JSF view in the example demonstrates this technique. Chapter 3 ■ The Basics of JavaServer Faces 129 The third view in the example, named recipe03_05c.xhtml, demonstrates conditional navigation. Its h:commandButton action invokes the login method within the NavigationController managed bean. That method does not contain much business logic in this example, but it does set the bean’s authenticated field equal to true. Imagine that someone entered an incorrect password and failed to authenticate; in such a case, then the authenticated field would be set to false. After the login method is executed, the faces-config.xml file is parsed for the next view to render, and the conditional navigation rule utilizes JSF EL to specify the navigation condition. The from-action element is set equal to the JSF EL that is used to invoke the login method, and an element is specified, referencing the navigationController.authenticated field via JSF EL. If that field is equal to true, then the view specified within the to-view-id element will be rendered. Note that the is required to tell JSF to redirect to the view listed in the element since JSF uses a redirect rather than a forward.   #{navigationController.login} #{navigationController.authenticated} /chapter03/recipe03_05d.xhtml   Standard JSF navigation allows enough flexibility for most cases, and its architecture is much more sophisticated than other web frameworks. However, in JSF 2.0, two new navigational techniques known as implicit and conditional navigation were introduced. With the addition of the new techniques, JSF navigation is more robust and easier to manage. 3-6. Updating Messages Without Recompiling Problem Rather than hard-coding messages into your managed bean classes, you want to specify the messages within a property file so that they can be edited on the fly. Solution Create a resource bundle, and specify your messages within it. Then retrieve the messages from the bundle and add them to the FacesMessages objects rather than hard-coding a String value. In the example that follows, a resource bundle is used to specify a message that is to be displayed on a page. If you need to change the message at any time, simply modify the resource bundle and reload the page in the browser. The following code is for a JSF view that contains the h:messages component for displaying the message from a corresponding managed bean:   Chapter 3 ■ The Basics of JavaServer Faces 130 Recipe 3-6: Specifying Updatable Messages

Utilizing a resource bundle

The message below is displayed from a resource bundle. The h:outputText component has been added to the page only to instantiate the bean for this example. To change the message, simply modify the corresponding message within the bundle and then refresh the page.


  Next, the managed bean class is responsible for creating the message and sending it to the h:messages component via the FacesContext. The following source is for ExampleController, which is the managed bean for the JSF view in this example:   package org.javaeerecipes.chapter03.recipe03_06;   import java.util.ResourceBundle; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext;   @ManagedBean(name = "exampleController") @RequestScoped public class ExampleController { private String exampleProperty;   /** * Creates a new instance of ExampleController */ public ExampleController() { exampleProperty = "Used to instantiate the bean."; FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, ResourceBundle.getBundle("/org/javaeerecipes/chapter03/Bundle"). getString("ExampleMessage"), null); FacesContext.getCurrentInstance().addMessage(null, facesMsg); }   Chapter 3 ■ The Basics of JavaServer Faces 131 /** * @return the exampleProperty */ public String getExampleProperty() { return exampleProperty; }   /** * @param exampleProperty the exampleProperty to set */ public void setExampleProperty(String exampleProperty) { this.exampleProperty = exampleProperty; } }   The resource bundle, which contains the message, is read by the managed bean to obtain the message. If you want to update the message, you can do so without recompiling any code.   # This file is an example resource bundle ExampleMessage=This message can be changed by updating the message bundle!   When the page is loaded, the h:outputText component instantiates ExampleController, which in turn creates the FacesMessage objects that are used to display the message on the screen. How It Works Oftentimes it is useful to have the ability to update custom system or user messages rather than hard-coding them. This could be useful in the case that some custom information that is contained within a particular message may have the possibility of changing in the future. It’d be nice to simply update the message in text format rather than editing the code, recompiling, and redeploying your application. It is possible to create updateable messages using a resource bundle. A resource bundle is simply a properties file, which contains name-value pairs. When adding custom messages to a bundle, name the message appropriately and then add the custom message as the value portion of the property. An application can then look up the property by name and utilize its value. In this case, the value is a String that will be used to create a FacesMessage instance. In the example, the bundle contains a property named ExampleMessage, along with a corresponding value. When the JSF view is loaded into the browser, the ExampleController managed bean is instantiated, causing its constructor to be executed. A FacesMessage instance is created, generating a message of type FacesMessage.SEVERITY_INFO, and it reads the resource bundle and obtains the value for the ExampleMessage property. The following excerpt demonstrates how to obtain a specified message value from the resource bundle:   ResourceBundle.getBundle("/org/javaeerecipes/chapter03/Bundle").getString("ExampleMessage"), null);   After the message is created, it is added to the current instance of FacesContext and, subsequently, displayed on the page when it is rendered. Using a resource bundle to specify your messages can make life much easier because you’ll no longer be required to recompile code in order to update such messages. Chapter 3 ■ The Basics of JavaServer Faces 132 3-7. Validating User Input Problem You want to add the ability for your application to validate any data that is entered into a JSF form. Solution Register a JSF validator on any text field components or other input components that need to be validated. Use predefined JSF validators where applicable, and create custom validator classes when needed. The example for this recipe utilizes predefined validators for two h:inputText components in order to ensure that the values entered into them are of proper length. A custom validator is added to a third text field, and it is responsible for ensuring that the text contains a specified String. The three fields make up an employee input form, and when an employee is entered and the data validates successfully, a new Employee object is created and added to a list of employees. An h:dataTable element in the view is used to display the list of employees if there are any. This is perhaps not the most true-to-life example, but you can apply the basic philosophy to validate real-world needs within your own applications. The following listing is for the JSF view that constructs the employee input form, including the validation tags for each input text field:   Recipe 3-7: Validating Data

Java Developer Employee Information



Current Employees Employee Chapter 3 ■ The Basics of JavaServer Faces 133 Title

Please use the form below to insert employee information.

  The third h:inputText component in the view utilizes a custom validator. The f:validator tag is used to specify a custom validator, and its validatorId attribute is used to specify a corresponding validator class. The following listing is the Java code for a class named EmployeeTitleValidate, the custom validation class for the text field:   package org.javaeerecipes.chapter03.recipe03_07;   import java.util.Date; import java.util.Locale; import java.util.ResourceBundle; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.validator.FacesValidator; import javax.faces.validator.Validator; import javax.faces.validator.ValidatorException; ChapTEr 3 ■ ThE BaSICS oF JavaSErvEr FaCES 134 /** * * @author juneau */ @FacesValidator("employeeTitleValidate") public class EmployeeTitleValidate implements Validator { @Override public void validate(FacesContext facesContext, UIComponent uiComponent, Object value) throws ValidatorException { checkTitle(value); } private void checkTitle(Object value) { String title = value.toString(); if (!title.contains("Java")) { String messageText = "Title does not include the word Java"; throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, messageText, messageText)); } } } Now let’s take a look at the JSF managed bean for the JSF view that contains the validation tags. The managed bean class is named EmployeeController, and the action method, insertEmployee, is used to add new Employee objects containing valid data to an ArrayList. package org.javaeerecipes.chapter03.recipe03_07; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.ResourceBundle; import javax.faces.bean.SessionScoped; import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext; import javax.faces.bean.ManagedBean; /** * Recipe 3-7 * @author juneau */ @ManagedBean(name = "employeeController") @SessionScoped public class EmployeeController implements Serializable { private String employeeFirst; private String employeeLast; private String employeeTitle; Chapter 3 ■ The Basics of JavaServer Faces 135 private List employeeList;   public EmployeeController(){ employeeFirst = null; employeeLast = null; employeeTitle = null; employeeList = new ArrayList(); }   public void insertEmployee(){ Employee emp = new Employee(employeeFirst, employeeLast, employeeTitle); employeeList.add(emp); FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Employee Successfully Added", null); FacesContext.getCurrentInstance().addMessage(null, facesMsg); }   /** * @return the employeeFirst */ public String getEmployeeFirst() { return employeeFirst; }   /** * @param employeeFirst the employeeFirst to set */ public void setEmployeeFirst(String employeeFirst) { this.employeeFirst = employeeFirst; }   /** * @return the employeeLast */ public String getEmployeeLast() { return employeeLast; }   /** * @param employeeLast the employeeLast to set */ public void setEmployeeLast(String employeeLast) { this.employeeLast = employeeLast; }   /** * @return the employeeTitle */ Chapter 3 ■ The Basics of JavaServer Faces 136 public String getEmployeeTitle() { return employeeTitle; }   /** * @param employeeTitle the employeeTitle to set */ public void setEmployeeTitle(String employeeTitle) { this.employeeTitle = employeeTitle; }   /** * @return the employeeList */ public List getEmployeeList() { return employeeList; }   /** * @param employeeList the employeeList to set */ public void setEmployeeList(List employeeList) { this.employeeList = employeeList; } }   Finally, the Employee class is a POJO that declares three fields: employeeFirst, employeeLast, and employeeTitle. Each of these three fields is declared as private, and there are accessor methods that are used by the JSF view for accessing the fields.   package org.javaeerecipes.chapter03.recipe03_07;   import java.io.Serializable;   /** * Recipe 3-7 * @author juneau */ public class Employee implements Serializable { private String employeeFirst; private String employeeLast; private String employeeTitle;   /** * Creates a new instance of EmployeeController */ public Employee() { employeeFirst = null; employeeLast = null; employeeTitle = null; }   Chapter 3 ■ The Basics of JavaServer Faces 137 public Employee(String first, String last, String title){ employeeFirst = first; employeeLast = last; employeeTitle = title; } /** * @return the employeeFirst */ public String getEmployeeFirst() { return employeeFirst; }   /** * @param employeeFirst the employeeFirst to set */ public void setEmployeeFirst(String employeeFirst) { this.employeeFirst = employeeFirst; }   /** * @return the employeeLast */ public String getEmployeeLast() { return employeeLast; }   /** * @param employeeLast the employeeLast to set */ public void setEmployeeLast(String employeeLast) { this.employeeLast = employeeLast; }   /** * @return the employeeTitle */ public String getEmployeeTitle() { return employeeTitle; }   /** * @param employeeTitle the employeeTitle to set */ public void setEmployeeTitle(String employeeTitle) { this.employeeTitle = employeeTitle; } }   In the end, the validators will raise exceptions if a user attempts to enter an employee first or last name using an invalid length or a title that does not contain the word Java. When user input validation fails, error messages are displayed next to the components containing the invalid entries. Chapter 3 ■ The Basics of JavaServer Faces 138 How It Works The JSF framework contains many features that make it more convenient for developers to customize their applications. Validators are one of those features, because they can be used to solidify application data and ensure data is correct before storing in a database or other data store. The JSF framework ships with a good deal of validators that are already implemented. To use these predefined validators, simply embed the appropriate validator tag within a component tag in a view to validate that component’s data values. Sometimes there are cases where the standard validators will not do the trick. In such cases, JSF provides a means for developing custom validator classes that can be used from within a view in the same manner as the predefined validators. In the example for this recipe, two of the h:inputText components contain standard JSF validators used to validate the length of the values entered. The f:validateLength tag can be embedded into a component for String length validation, and the tag’s minimum and maximum attributes can be populated with the minimum and maximum String length, respectively. As mentioned previously, JSF ships with a good number of these predefined validators. All that the developer is required to do is embed the validator tags within the components that they want to validate. Table 3-3 lists all standard validator tags and what they do. For a detailed look at each of the validator attributes, please see the online documentation. Table 3-3.  Standard Validators Validator Tag Description validateLength Checks the length of a String validateLongRange Checks the range of a numeric value validateDoubleRange Checks the range of a floating-point value validateRequired Ensures the input field is not empty (also an alternative to using the required attribute on an input field component tag) validateRegex Validates the component against a given regular expression pattern Oftentimes, there is a need for some other type of validation to take place for a specified component. In such cases, developing a custom validator class may be the best choice. Many developers shy away from writing their own validators, because it seems to be a daunting task at first glance. However, JSF 2.0 took great strides toward making custom validator classes easier to write and understand. To create a custom validator class, implement the javax.faces.validator.Validator class. Annotate the validator class with the @FacesValidator annotation, specifying the string you want to use for registering your validator within the f:validator tag. In the example, the name used to reference the validator class is employeeTitleValidate. The only requirement is that the validator class overrides the validate method, which is where the custom validation takes place. The validate method contains the following signature:   public void validate(FacesContext facesContext, UIComponent uiComponent, Object value) throws ValidatorException   Utilizing the parameters that are passed into the method, you can obtain the current FacesContext, a handle on the component being validated, as well as the component’s value. In the example, a helper method is called from within the validate method, and it is used to check the component’s value and ensure that the word Java is contained somewhere within it. If it does not validate successfully, a ValidatorException is created and thrown. The message that is placed within the ValidatorException is what will appear next to the component being Chapter 3 ■ The Basics of JavaServer Faces 139 validated if the validation fails. The following excerpt from the validation class demonstrates creating and throwing a ValidatorException:   throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, messageText, messageText));   So, when does the validation occur? That is the key to the validator, isn’t it? The answer is immediately, before the request is sent to the managed bean action method. Any validation occurs during the process validation phase, and if one or more components being validated within a view throw a ValidatorException, then the processing stops, and the request is not sent to the action method. When the user clicks the submit button, the validation takes place first, and if everything is OK, then the request is passed to the action method. Note■■ a means of validating that an input component simply contains a value is to use the required attribute. The required attribute of input component tags can be set to true in order to force a value to be entered for that component. The validation of components within a JSF view using standard validators can really save a developer some time and increase the usability and precision of an application. The ability to create custom validators allows validation to be performed for any scenario. Be constructive, use validation on all of your application’s input forms, and create custom validators to perform validation using unique techniques. Your application users will appreciate it! 3-8. Evaluation of Page Expressions Immediately Problem You want to have some of your JSF component values evaluated immediately, rather than waiting until the form is submitted. Solution Specify true for the component tag’s immediate attribute, and also specify the component’s onchange attribute and set it equal to submit(). This will cause the input form to be submitted immediately when the value for the component is changed, and JSF will skip the render response phase when doing so and will execute all components that specify an immediate attribute set to true during the Apply Request Values phase. The example for this recipe uses the same employee form that was demonstrated in Recipe 3-7. However, instead of waiting until the form is submitted, the first and last h:inputText components will be evaluated and validated during the Apply Request Values phase immediately when their values change. The following source is for the JSF view named recipe03_08.xhtml:   Chapter 3 ■ The Basics of JavaServer Faces 140 Recipe 3-8: Immediate View Evaluation

Java Developer Employee Information



Current Employees Employee Title

Please use the form below to insert employee information. The first and last text fields will result in immediate evaluation during the apply request values phase, whereas the text field in the middle will result in standard evaluation and be validated during the invoke application phase.

To test, try inserting just one character in the first text field and then tab to the next field. You should see an immediate result.

Chapter 3 ■ The Basics of JavaServer Faces 141
  As you can see, the h:inputText components with ids of employeeFirst and employeeTitle specify both the immediate="true" and the onchange="submit()" attributes. These two attributes cause the components to be validated immediately rather than when the h:commandButton action is invoked. How It Works Event handling that occurs immediately can be useful in cases where you do not want to validate the entire form in order to process input but, rather, when you want chosen components to be validated immediately. As mentioned in Recipe 3-1, when a JSF view is processed, a number of phases are executed. As such, when a form is submitted, the Invoke Application phase initiates the event handlers for view components, and validation occurs. When the immediate attribute for a component is set to true, the event handlers for that component execute during the Apply Request Values phase, which occurs before the Process Validation phase, where component validation normally occurs. This allows for an immediate validation response for the specified components, resulting in immediate error messages if needed. As mentioned previously, specify the immediate attribute for a component and set it to true if you want to have that component evaluated immediately. This will cause the component to be evaluated and validated during the Apply Request Values phase. The real fun comes into play when you also specify the onclick attribute and set it equal to submit(), causing the form to be submitted when the value for the component changes. Specifying attributes as such will cause any component within the view that has an immediate attribute set to true to be validated when the component value changes. Note■■   The immediate attribute can also be useful when used on a commandButton component in such instances where you do not want any form processing to take place, such as if you want to set up a Cancel button or another button that bypasses form processing. 3-9. Passing Page Parameters to Methods Problem You want to pass parameters to managed bean methods from within a JSF view. Solution Use a standard JSF EL expression to invoke a managed bean method, and enclose the parameters that you want to pass to the method within parentheses. In the example for this recipe, an h:dataTable component is used to display a list of Author objects in a view. Each row within the h:dataTable contains an h:commandLink component, which Chapter 3 ■ The Basics of JavaServer Faces 142 invokes a JSF managed bean method when selected. The h:commandLink displays the current row’s author name and invokes the AuthorController class displayAuthor method when clicked, passing the last name for the author being displayed in the current row. In the displayAuthor method, the list of authors is traversed, finding the element that contains the same last name as the parameter, which is passed into the method. The current author is then displayed in a subsequent page, which is rendered using implicit navigation. The following source is for the JSF view entitled recipe03_09a.xhtml, which displays the list of authors using an h:dataTable component:   Recipe 3-9: Passing Page Parameters to Methods

Author List

Below is the list of authors. Click on the author's last name for more information regarding the author.


Java 7 Recipes Authors

  
  Chapter 3 ■ The Basics of JavaServer Faces 143 The next listing is that of the managed bean controller for the preceding JSF view. The managed bean populates an ArrayList with Author objects upon instantiation.   package org.javaeerecipes.chapter03.recipe03_09;   import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped;   /** * Recipe 3-9 * * @author juneau */ @ManagedBean(name = "authorTableController") @SessionScoped public class AuthorController implements Serializable {   private List authorList = null; private String juneauBio = "Josh Juneau has been developing software" + " since the mid-1990s. PL/SQL development and database programming" + " was the focus of his career in the beginning, but as his skills developed," + " he began to use Java and later shifted to it as a primary base for his" + " application development. Josh has worked with Java in the form of graphical" + " user interface, web, and command-line programming for several years. " + "During his tenure as a Java developer, he has worked with many frameworks" + " such as JSF, EJB, and JBoss Seam. At the same time, Josh has extended his" + " knowledge of the Java Virtual Machine (JVM) by learning and developing applications" + " with other JVM languages such as Jython and Groovy. His interest in learning" + " new languages that run on the JVM led to his interest in Jython. Since 2006," + " Josh has been the editor and publisher for the Jython Monthly newsletter. " + "In late 2008, he began a podcast dedicated to the Jython programming language.";   private String deaBio = "This is Carl Dea's Bio"; private String beatyBio = "This is Mark Beaty's Bio"; private String oConnerBio = "This is John O'Connor's Bio"; private String guimeBio = "This is Freddy Guime's Bio"; private Author current; /** * Creates a new instance of RecipeController */ public AuthorController() { populateAuthorList(); }   private void populateAuthorList() {   if(authorList == null){ System.out.println("initializng authors list"); ChapTEr 3 ■ ThE BaSICS oF JavaSErvEr FaCES 144 authorList = new ArrayList(); authorList.add(new Author("Josh", "Juneau", juneauBio)); authorList.add(new Author("Carl", "Dea", deaBio)); authorList.add(new Author("Mark", "Beaty", beatyBio)); authorList.add(new Author("John", "O'Conner", oConnerBio)); authorList.add(new Author("Freddy", "Guime", guimeBio)); } } public String displayAuthor(String last){ for(Author author:authorList){ if(author.getLast().equals(last)){ current = author; break; } } return "recipe03_09b"; } /** * @return the authorList */ public List getAuthorList() { System.out.println("Getting the authorlist =>" + authorList.size()); return authorList; } /** * @return the current */ public Author getCurrent() { return current; } /** * @param current the current to set */ public void setCurrent(Author current) { this.current = current; } } The Author class is the same Author POJO that was utilized in Recipe 3-3. For the source of the Author class, please refer to that recipe. Lastly, the following code is for a JSF view entitled recipe03_09b.xhtml, the detail view for each author. When an author name is clicked from the h:dataTable component in the first view, the component’s corresponding managed bean method is invoked, and then this view is rendered to display the selected author’s information. Chapter 3 ■ The Basics of JavaServer Faces 145 Recipe 3-9: Passing Page Parameters to Methods

#{authorTableController.current.first} #{authorTableController.current.last}


#{authorTableController.current.bio}

  
  How It Works The release of JSF 2.0 contained many enhancements that made the life of JSF developers much easier than before. The ability to pass parameters to managed bean methods from within JSF views is one such enhancement. As you can see from the example for this recipe, it is possible to pass parameters to a method within a JSF EL construct in the same manner that you would call any method with parameters in Java: by enclosing the argument(s) within parentheses after the method name. It cannot get much simpler than that! Let’s take a look at the lines of code that make this example hum. The first JSF view displays a table of author names, and each name is displayed using an h:commandLink component. The value attribute for the h:commandLink component is set to the author name, and the action attribute is set to the JSF EL, which invokes a managed bean action method named displayAuthor. Notice that within the call to the managed bean method, the EL for the author’s last name is passed as a String parameter.   Java 7 Recipes Authors Chapter 3 ■ The Basics of JavaServer Faces 146   The displayAuthor method within the managed bean accepts a String parameter value, which is the author’s last name, and then finds an Author object within the list of authors that contains the same last name. When found, a class field named current is set equal to the Author object for the matching List element. The subsequent JSF view then displays content utilizing the current Author information. Prior to JSF 2.0, developers were unable to pass parameters to managed bean methods from within a view. This made it a bit more difficult to perform such techniques and usually involved a bit more code. 3-10. Arithmetic and Reserved Words in Expressions Problem You want to perform some arithmetic and combine expressions within your JSF views. Solution JSF EL expressions can contain arithmetic using standard arithmetic operators. It is also possible to combine two or more expressions utilizing some of JSF ELs reserved words. In the following example, some JSF EL expressions are used to display mathematical results on a page. Both the usage of arithmetic and reserved words are used within the expressions.   Recipe 3-10: Arithmetic and Reserved Words

JSF Arithmetic and Reserved Words in EL

The following examples use JSF EL to perform some arithmetic.

Chapter 3 ■ The Basics of JavaServer Faces 147 1 + 1 = #{1 + 1}




This will be displayed if expr1() evaluates to true.
This will be displayed if expr2() or field1 evaluates to true.
  Some of the expressions contain managed bean references for a bean named EvaluationController. The listing for this managed bean is as follows:   package org.javaeerecipes.chapter03.recipe03_10;   import javax.faces.bean.Named; import javax.faces.bean.RequestScoped;   /** * Recipe 3-10 * @author juneau */ @ManagedBean(name = "evaluationController") @RequestScoped public class EvaluationController {   private boolean field1 = true;   /** * Creates a new instance of EvaluationController */ public EvaluationController() { }   public boolean expr1(){ return true; }   Chapter 3 ■ The Basics of JavaServer Faces 148 public boolean expr2(){ return false; }   /** * @return the field1 */ public boolean isField1() { return field1; }   /** * @param field1 the field1 to set */ public void setField1(boolean field1) { this.field1 = field1; } }   The resulting page will look as follows:   The following examples use JSF EL to perform some arithmetic. 1 + 1 = 2 20 / 5 = 4.0 1 + 1 DOES equal 2   Combining some expressions This will be displayed if expr1() evaluates to true. This will be displayed if expr1() or field1 evaluates to true.   How It Works It is possible to use standard arithmetic and combine expressions using reserved words within JSF EL expressions. All standard arithmetic operators are valid within EL, but a couple of things are different. For instance, instead of writing an expression such as #{1 + 1 = 2}, you could use the eq reserved characters so that the expression reads #{1 + 1 eq 2}. Similarly, the != symbol could be used to specify that some value is not equal to another value, but rather, in this example, the ne reserved word is used. Table 3-4 describes all such reserved words. Chapter 3 ■ The Basics of JavaServer Faces 149 Table 3-5 lists the available operators that can be used within JSF EL expressions, in order of precedence. Table 3-4.  JSF EL Reserved Words Reserved Word Description and Combines two or more expressions div Used to divide empty Used to refer to an empty list eq Equal to false Boolean false ge Greater than or equal to gt Greater than instanceof Used to evaluate whether an object is an instance of another le Less than or equal lt Less than mod Modulus ne Not equal not Used for negation null Evaluates a null value or Combines two or more expressions true Boolean true Table 3-5.  Operators for Use in Expressions Operator [] () - (unary), not, !, empty *, /, div, %, mod +, - (binary) <, >, <=, >=, lt, gt, le, ge ==, !, eq, ne &&, and ||, or ?, : Chapter 3 ■ The Basics of JavaServer Faces 150 3-11. Creating Bookmarkable URLs Problem You want to enable your application to allow URLs that will be linked to display specific objects. For instance, you want to use a GET URL such as http://myserver.com/JavaEERecipes/chapter03/chapter03_11.xhtml?last=juneau in order to display a page containing information on the author with the specified last name. Solution Add view parameters to a JSF view for which you want to create a bookmarkable URL by defining the parameter in an f:viewParam tag, which is a subtag of the f:metadata tag. Doing so will allow a page to become accessible via a URL that contains request parameters that can be used for record identification. In this example, the view contains a view parameter, via the f:viewParam tag, that allows for the specification of an author’s last name when the view is requested. For the example, the managed bean that was created in Recipe 3-9 has been modified to include a new property named authorLast in order to accommodate the new view parameter. The sources for the view named recipe03_11.xhtml are listed next. They are very similar to the view named recipe03_09b.xhtml, except that they include an f:viewParam element, which is enclosed between opening and closing f:metadata elements.   Recipe 3-11: Creating Bookmarkable URLs

#{authorTableController.current.first} #{authorTableController.current.last}


#{authorTableController.current.bio}

   Chapter 3 ■ The Basics of JavaServer Faces 151
  The updated code for the org.javaeerecipes.chapter03.recipe03_09.AuthorController managed bean class is listed next:   package org.javaeerecipes.chapter03.recipe03_09;   import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.faces.ManagedBean; import javax.faces.bean.SessionScoped;   @ManagedBean(name = "authorTableController") @SessionScoped public class AuthorController implements Serializable {   ... private String authorLast; ...   /** * @return the authorLast */ public String getAuthorLast() { return authorLast; }   /** * @param authorLast the authorLast to set */ public void setAuthorLast(String authorLast) { displayAuthor(authorLast); } }   As mentioned previously, a property has been added to the bean named authorList. This property makes it possible for the JSF view listed in the example to accept a request parameter named authorList via a GET URL and pass it to the bean when the page is requested. In the end, the URL for accessing the view and requesting the details for the author Josh Juneau would be as follows:   http://my-server.com/JavaEERecipes/chapter03/chapter03_11.xhtml?authorLast=Juneau   Chapter 3 ■ The Basics of JavaServer Faces 152 How It Works In the past, JSF applications had a weakness in that they used to require a launch view, which created an entry point for accessing the application. This gave the application a view that would set up an initial state for the application session. While this concept is nice because each user session would begin their session with an initialized application state, it prohibited the ability for records to be linked directly via a URL. Sometimes it is very useful to have the ability to link a view to a URL that contains request parameters so that record(s) matching the given parameters can be returned to the view without further user interaction; for instance, say a web site included information regarding a book and wanted to include a URL to find out more about the book’s author. It’s much nicer to directly link to a view containing that author’s information rather than redirecting the user to a web site that requires them to perform a manual search for the author. Such URLs are also known as bookmarkable URLs because the URL contains all of the state that is required to make the request. Therefore, they allow the user of a web application to bookmark the URL for direct access to a specific point within an application. JSF 2.0 introduced the ability to include view parameters, adding the ability for views to accept request parameters. Utilizing a GET-based URL, a request parameter can be appended to the end along with its value, and a view containing the new view parameter can then pass the parameter to a managed bean before the response is rendered. The bean can then accept the parameter value and query a database or search through some other collection of data to find a record that matches the given value before rendering the response. To include one or more view parameters within a view, you must add an opening and closing f:metadata element to the view and embed the number of f:viewParam elements between them. The f:viewParam element includes two attributes that must have values, those being the name and value attributes. The name attribute specifies the name of the request parameter as you would like it to appear within the bookmarkable URL, and the value attribute specifies the managed bean field that should be mapped to that request parameter. In the example for this recipe, the JSF view contains a view parameter named authorLast, and the associated authorLast field within the managed bean contains a setter method, which is invoked when the page is requested. The following excerpt from the view demonstrates the lines for adding the metadata and view parameter:     With the addition of the view parameter, the page can be requested with a URL containing the authorLast request parameter as follows:   http://my-server.com/JavaEERecipes/chapter03/chapter03_11.xhtml?authorLast=Juneau   When the page is requested, the view parameter’s value invokes the setAuthorLast method within the managed bean, which then searches for an author record that contains a last name equal to the given request parameter value.   ... public void setAuthorLast(String authorLast) { displayAuthor(authorLast); } ...   The addition of view parameters to JSF 2.0 has made it easy to create bookmarkable URLs. This allows applications to be more flexible and produce results immediately without requiring a user to navigate through several pages before producing a result. Chapter 3 ■ The Basics of JavaServer Faces 153 3-12. Displaying Lists of Objects Problem You want to display a list of objects within your rendered JSF page. Solution Use a JSF h:dataTable component to display the list objects, iterating over each object in the list and displaying the specified values. The h:dataTable component is very customizable and can be configured to display content in a variety of layouts. The following JSF view contains two h:dataTable components that are used to display the authors for the Java 7 Recipes book using managed beans developed in previous recipes. The first table in the view is straightforward and displays the names of each author. It has been formatted to display alternating row colors. The second table contains two rows for each corresponding list element, displaying the author names on the first row and their bios on the second.   Recipe 3-12: Displaying Lists of Objects


#{authorTableController.current.bio}

Java 7 Recipes Authors ChapTEr 3 ■ ThE BaSICS oF JavaSErvEr FaCES 154

Java 7 Recipes Authors
The example utilizes a cascading style sheet to help format the colors on the table. The source for the style sheet is as follows: .authorTable{ border-collapse:collapse; } .authorTableOdd{ text-align:center; background:none repeat scroll 0 0 #CCFFFF; border-top:1px solid #BBBBBB; } .authorTableEven{ text-align:center; background:none repeat scroll 0 0 #99CCFF; border-top:1px solid #BBBBBB; } The resulting page should look similar to Figure 3-4. Chapter 3 ■ The Basics of JavaServer Faces 155 Figure 3-4.  JSF DataTable component examples How It Works A JSF h:dataTable component can be used to display lists of objects within a page. When rendered, an HTML table is constructed, populating the cells of the table with the data for each list element or record of data. The h:dataTable can iterate over a collection of data, laying it out in a columnar format including column headers and the ability to customize the look using Cascading Style Sheets (CSS). The component contains a number of important attributes, as listed in Table 3-6. Perhaps the most important of them are the value and var attributes. The value attribute Chapter 3 ■ The Basics of JavaServer Faces 156 specifies the collection of data to iterate, and the var attribute lists a String that will be used to reference each individual row of the table. The collection usually comes from the managed bean, such as in the example for this recipe. The legal data types for the value attribute are Array, DataModel, List, and Result. The var attribute is used within each column to reference a specific field within an object for the corresponding row. Table 3-6.  DataTable Attributes Attribute Description id ID for the component border An integer indicating border thickness; 0 is default bgcolor Background color of table cellpadding Padding between the cell wall and its contents cellspacing Spacing within the cells width Overall width of the table, specified in pixels or percentages first The first entry in the collection to display rows Total number of rows to display styleClass, captionClass, headerClass, footerClass, rowClasses, columnClasses CSS attributes rendered Boolean value indicating whether the component will be rendered The h:dataTable can contain any number of columns, and each is specified within the h:dataTable component in the JSF view. The h:column nested element encloses the output for each column. A column can contain just about any valid component or HTML, even embedded dataTables. An h:column normally does not have any attributes specified, but it always contains an expression or hard-coded value for display.   my column value   or   #{myTable.myColValue}   Normally, columns within an HTML table contain headers. You can add headers to the h:dataTable or individual columns by embedding an f:facet element within the h:dataTable and outside of the column specifications or within each h:column by specifying the name attribute as header. The f:facet element can also specify caption for the name attribute in order to add a caption to the table. The following excerpt from the example demonstrates an h:dataTable that includes each of these features:   Java 7 Recipes Authors Chapter 3 ■ The Basics of JavaServer Faces 157   In the example, you can see that the h:dataTable value attribute is listed as #{authorTableController. authorList}, a List of Author objects declared within the managed bean. The var attribute establishes a variable named author that refers to the current author who is being processed from the author list. The author variable can then be accessed from within each h:column, displaying the data associated with the current list element. An important piece of the puzzle to help make tables easier to read and follow is the CSS that can be used to style the table. The h:dataTable supports various attributes that allow you to apply externally defined CSS classes to your table, specifically, the styleClass, captionClass, headerClass, footerClass, rowClasses, and columnClasses attributes. Each of them can contain a CSS class specification for formatting. The example demonstrates this feature. 3-13. Invoking Managed Bean Actions on Life-Cycle Phase Events Problem You want to automatically invoke a managed bean action when a specific JSF life-cycle phase event occurs. For instance, when a view is loading, you want to invoke a managed bean action that performs a conditional verification based upon the user who is visiting the page. Solution Utilize a JSF view action by adding the f:viewAction facet to the JSF view. Use the facet to specify the managed bean action to invoke, as well as when to invoke the action. In the following excerpt from the view chapter03/ recipe03_13.xhtml, a managed bean method action named validateUser is invoked:     How It Works In JSF 2.1 and prior, it was difficult to invoke action methods within a managed bean unless they were bound to a command component. Sometimes it makes sense to invoke a method when the page is loading, after the page has been fully loaded, and so on. In the past, this was done by using a preRenderView event listener, which invokes a method contained within a managed before the view is rendered. Utilization of the preRenderView event listener works, but it does not provide the level of control that is required to invoke a method during different phases of the view life cycle. The preRenderView also requires developers to programmatically check the request type and work with the navigation handler. In the JSF 2.2 release, a new technique can be used to invoke action methods within a managed bean during specified life-cycle events that occur within the view. A new tag, f:viewAction, can be bound to a view, and it can be incorporated into the JSF life cycle in both non-JSF (initial) and JSF (postback) requests. To use the tag, it must be a child of the metadata facet. View parameters can be specified within the metadata facet as well, and they will become available from within the managed bean when the action method is invoked. In the example, the action method named validateUser is invoked using the viewAction. In the example method, a String is returned, which enables implicit navigation based upon the action method results. If null is returned, the navigation handler is invoked, but the same view will be rendered again so long as there are no Chapter 3 ■ The Basics of JavaServer Faces 158 navigation condition expressions that change the navigation. If a String-based view name is returned, then the navigation handler will render that view once the method has completed. This can come in handy for situations such as authentication handling, where an action method is used to check the user’s role and then the appropriate view is rendered based upon the authenticated user role.   public String validateUser() { String viewName; System.out.println("Look in the server log to see this message"); // Here we would perform validation based upon the user visiting the // site to ensure that they had the appropriate permissions to view // the selected view. For the purposes of this example, this // conditional logic is just a prototype. if (visitor.isAdmin()){ // visit the current page viewName = null; System.out.println("Current User is an Admin"); } else { viewName = "notAdmin"; System.out.println("Current User is NOT an Admin"); } return viewName; }   As mentioned previously, f:viewAction facet can be customized to allow the action method to be invoked at different stages within the view life cycle. By default, the viewAction will be initiated before postback because the specified action method is expected to execute whether the request was Faces or non-Faces. However, this can be changed by setting the onPostback attribute of the f:viewAction tag to true.     If you need to get even more granular and invoke a view action during specified life-cycle phase, it is possible by setting the phase attribute to the phase required. Table 3-7 specifies the different phases along with their phase value. Table 3-7.  JSF Life-Cycle Phases Phase Tag Value Restore View RESTORE_VIEW Apply Request Values APPLY_REQUEST_VALUES Process Validations PROCESS_VALIDATIONS Update Model Values UPDATE_MODEL_VALUES Invoke Application INVOKE_APPLICATION Render Response RENDER_RESPONSE The following example demonstrates the f:viewAction facet that will cause the action to be invoked during the Process Validations phase:     159 Chapter 4 Facelets In the early days of web development, web pages consisted of many HTML tables for structuring layout and lots of redundancy across application pages. This made development of web pages cumbersome and difficult to maintain at best. Over the years, other technologies such as Cascading Style Sheets (CSS) have come along to help web developers organize and style their pages. Such technologies encouraged organization by allowing developers to encapsulate styles into separate files, leaving the markup within pages easier to follow. Other technologies such as Tiles came along to help reduce the amount of redundancy that was incurred by providing a similar layout to all pages of an application. Tiles allowed developers to construct a single layout and apply it to several different web pages. Facelets is a view definition language that was introduced to help organize JSF views. Facelets follows in the footsteps of Tiles, in that it allows developers to encapsulate layouts into separate files and apply them to different JSF views. . . and that functionality only scratches the surface! While Facelets can be used to create layouts and build templates for JSF applications, it also brings with it many other significant advantages. Facelets became the default view definition language of JSF with the release of JSF 2.0. Prior to that, Facelets had to be applied to an application separately. Developers of JSF 2.0+ applications can begin to use Facelets out of the box, without any additional application configuration. In addition to helping build application templates, Facelets provides built-in components to facilitate iteration over collections of data, debugging, inserting view fragments into other views, and so forth. This chapter will cover an array of recipes to help developers gain an understanding of some beginning, intermediate, and advanced Facelets techniques. 4-1. Creating a Page Template Problem You want to make each of the JSF views within your application follow the same structure. Moreover, you want to have the ability to reuse the same layout for each view. Solution Create a page template using the Facelets view definition language. Facelets ships as part of JavaServer Faces, and you can use it to create highly sophisticated layouts for your views in a proficient manner. The template demonstrated in this recipe will be used to define the standard layout for all pages within an application. The demo application for this chapter is for a bookstore web site. The site will display a number of book titles on the left side of the screen, a header at the top, a footer at the bottom, and a main view in the middle. When a book title is clicked in the left menu, the middle view changes, displaying the list of authors for the selected book. Chapter 4 ■ Facelets 160 To create a template, you must first develop a new XHTML view file and then add the appropriate HTML/JSF/XML markup to it. Content from other views will displace the ui:insert elements in the template once the template has been applied to one or more JSF views. The following source is that of a template named custom_template.xhtml; this is the template that will be used for all views within the application:   #{faceletsAuthorController.storeName}

#{faceletsAuthorController.storeName}

Java 7 Recipes

Java EE 7 Recipes
Content
Written by Josh Juneau, Apress Author
    Chapter 4 ■ Facelets 161 The template defines the overall structure for the application views. However, it uses a CSS style sheet to declare the formatting for each of the
elements within the template. The style sheet, entitled default.css, should be contained within a resources directory in the application so that it will be accessible to the views. Note■■ the CSS style sheets are automatically generated for you if using the NetBeans IDE. There are also a couple of JSF EL expressions utilized within the template. The EL references a JSF managed bean by the name of AuthorController, which is referenced by faceletsAuthorController. While the source for this class is very important for the overall application, you’ll wait to look at that code until Recipe 4-2 since it does not play a role in the application template layout. How It Works To create a unified application experience, the views should be coherent in that they look similar and function in a uniform fashion. The idea of developing web page templates has been around for a number of years, but unfortunately many template implementations contain duplicate markup on every application page. While duplicating the same layout for every separate web page works, it creates a maintenance nightmare. What happens when there is a need to update a single link within the page header? Such a conundrum would cause a developer to visit and manually update every web page for an application if the template was duplicated on every page. The Facelets view definition language provides a robust solution for the development of view templates, and it is one of the major bonuses of working with the JSF technology. Facelets provides the ability for a single template to be applied to one or more views within an application. This means a developer can create one view that constructs the header, footer, and other portions of the template, and then this view can be applied to any number of other views that are responsible for containing the main view content. This technique mitigates issues such as changing a single link within the page header, because now the template can be updated with the new link, and every other view within the application will automatically reflect the change. To create a template using Facelets, create an XHTML view, declare the required namespaces, and then add HTML, JSF, and Facelets tags accordingly to design the layout you desire. The template can be thought of as an “outer shell” for a web view, in that it can contain any number of other views within it. Likewise, any number of JSF views can have the same template applied, so the overall look and feel of the application will remain constant. Figure 4-1 provides a visual demonstrating the concept of an application template. Figure 4-1.  Visual representation of a Facelets template and client Chapter 4 ■ Facelets 162 You may have noticed from the view listing in the solution to this recipe that there are some tags toting the ui: prefix. Those are the Facelets tags that are responsible for controlling the view layout. To utilize these Facelets tags, you’ll need to declare the XML namespace for the Facelets tag library in the element within the template. Note that the XML namespace for the standard JSF tag libraries is also specified here.   ...  Note■■ the Facelets template must include the , , or , and or , elements because they are what define the overall layout for each view that uses it. The and elements will be covered in detail in Chapter 5. Each view that makes use of a Facelets template is known as a composition. One template can be used by multiple compositions or views. In actuality, everything outside of the opening and closing tags within a composition is ignored. You’ll learn more about that in Recipe 4-2! Facelets contains a number of special tags that can be used to help control page flow and layout. Table 4-1 in Recipe 4-2 lists the Facelets tags that are useful for controlling page flow and layout. The only Facelets tag that is used within the template for this recipe example is ui:insert. The ui:insert tag contains a name attribute, which is set to the name of the corresponding ui:define element that will be included in the view. Taking a look at the source for this recipe, you can see the following ui:insert tag:   Content   If a view that uses the template, a.k.a. template client, specifies a ui:define tag with the same name as the ui:insert name, then any content that is placed between the opening and closing ui:define tags will be inserted into the view in that location. However, if the template client does not contain a ui:define tag with the same name as the ui:insert tag, then the content between the opening and closing ui:insert tags within the template will be displayed. Templates can be created via an IDE, such as NetBeans, to provide a more visual representation of the layout you are trying to achieve. To create a Facelets template from within NetBeans, right-click the project folder into which you want to place the template, and select New ➤ Other from the contextual menu to open the New File window. Once that’s open, select JavaServer Faces from the Category menu and then Facelets Template from within the file types, as shown in Figure 4-2. Chapter 4 ■ Facelets 163 After you’ve selected the Facelets Template file type, click the Next button to open the New Facelets Template window (Figure 4-3). This window will allow you to select the overall layout that you would like to compose for your application views, as well as choose the location and name for the template. Figure 4-2.  Creating a Facelets template from within NetBeans Chapter 4 ■ FaCelets 164 After you’ve selected the layout of your choice and filled in the other options, the template will be opened within the NetBeans code editor, and you can begin to apply the template to JSF view clients (see Recipe 4-2). Using a wizard such as the one offered by NetBeans can help since a visual representation of the template can be chosen at creation time. In summary, a Facelets template consists of HTML and JSF markup, and it is used to define a page layout. Sections of the template can specify where page content will be displayed through the usage of the ui:insert tag. Any areas within the template that contain a ui:insert tag can have content inserted into them from a template client. To learn more about applying a template to your views, please see Recipe 4-2. 4-2. Applying a Template to Your Views Problem You have created a template for use within your JSF web views and you want to apply it to the views of your application. Solution Use the ui:composition tag within each view that will utilize the template. The ui:composition tag should be used to invoke the template, and ui:define tags should be placed where content should be inserted. The following listings demonstrate how Facelets templates are applied to various views. Figure 4-3. New Facelets Template window in NetBeans Chapter 4 ■ Facelets 165 View #1: recipe04_01a.xhtml recipe04_01a.xhtml is the markup for a view within the bookstore application that is used to display the authors for the Java 7 Recipes book. The template that was created in Recipe 4-1 is applied to the view, and individual ui:define tags are used within the view to specify the content that should be inserted into the page/view.      

Author List for Java 7 Recipes

Below is the list of authors. Click on the author's last name for more information regarding the author.


Java 7 Recipes Authors

   Chapter 4 ■ Facelets 166
bottom
  View #2: recipe04_01b.xhtml recipe04_01b.xhtml contains the sources for the second view within the bookstore application. It is used to list the authors for the Java EE 7 Recipes book. Again, note that the template has been applied to the view by specifying the template attribute within the ui:composition tag.      

Author List for Java EE 7 Recipes

Below is the list of authors. Click on the author's last name for more information regarding the author.

  Chapter 4 ■ Facelets 167
Java 7 Recipes Authors

   
bottom
  View #3: recipe04_01c.xhtml recipe04_01c.xhtml contains the sources for another view listing that is part of the bookstore application. This view is responsible for displaying the individual author detail. Again, the template is applied to this page.   Recipe 4-1: Facelets Page Template Chapter 4 ■ Facelets 168

#{faceletsAuthorController.current.first} #{faceletsAuthorController.current.last}


#{faceletsAuthorController.current.bio}

bottom
  Managed Bean Controller: AuthorController Of course, all the business logic and navigation is occurring from within a JSF managed bean. AuthorController is the bean that handles all the logic for the bookstore application. Note that the @ManagedBean annotation specifies a String value of faceletsAuthorController, which is used to reference the bean from within the views.   package org.javaeerecipes.chapter04.recipe04_01;   import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped;   /** * Recipe 4-1 * * @author juneau */ Chapter 4 ■ Facelets 169 @ManagedBean(name = "faceletsAuthorController") @SessionScoped public class AuthorController implements Serializable {   private List authorList; private String storeName = "Acme Bookstore";   private String juneauBio = "Josh Juneau has been developing software" + " since the mid-1990s. PL/SQL development and database programming" + " was the focus of his career in the beginning, but as his skills developed," + " he began to use Java and later shifted to it as a primary base for his" + " application development. Josh has worked with Java in the form of graphical" + " user interface, web, and command-line programming for several years. " + "During his tenure as a Java developer, he has worked with many frameworks" + " such as JSF, EJB, and JBoss Seam. At the same time, Josh has extended his" + " knowledge of the Java Virtual Machine (JVM) by learning and developing applications" + " with other JVM languages such as Jython and Groovy. His interest in learning" + " new languages that run on the JVM led to his interest in Jython. Since 2006," + " Josh has been the editor and publisher for the Jython Monthly newsletter. " + "In late 2008, he began a podcast dedicated to the Jython programming language."; private String deaBio = "This is Carl Dea's Bio"; private String beatyBio = "This is Mark Beaty's Bio"; private String oConnerBio = "This is John O'Connor's Bio"; private String guimeBio = "This is Freddy Guime's Bio"; private Author current; private String authorLast;   /** * Creates a new instance of RecipeController */ public AuthorController() { populateJavaRecipesAuthorList(); }   pubilc String populateJavaRecipesAuthorList() {    authorList = new ArrayList<>(); authorList.add(new Author("Josh", "Juneau", juneauBio)); authorList.add(new Author("Carl", "Dea", deaBio)); authorList.add(new Author("Mark", "Beaty", beatyBio)); authorList.add(new Author("John", "O'Conner", oConnerBio)); authorList.add(new Author("Freddy", "Guime", guimeBio)); return "recipe04_01a"; }   public String populateJavaEERecipesAuthorList() { System.out.println("initializng authors list"); authorList = new ArrayList<>(); authorList.add(new Author("Josh", "Juneau", juneauBio)); return "recipe04_01b";   }   Chapter 4 ■ Facelets 170 public String displayAuthor(String last) { for (Author author : authorList) { if (author.getLast().equals(last)) { current = author; } } return "recipe04_01c"; }   /** * @return the authorList */ public List getAuthorList() { return authorList; }   /** * @return the current */ public Author getCurrent() { return current; }   /** * @param current the current to set */ public void setCurrent(Author current) { this.current = current; }   /** * @return the authorLast */ public String getAuthorLast() { return authorLast; }   /** * @param authorLast the authorLast to set */ public void setAuthorLast(String authorLast) { this.authorLast = authorLast; }   /** * @return the storeName */ public String getStoreName() { return storeName; }   Chapter 4 ■ Facelets 171 /** * @param storeName the storeName to set */ public void setStoreName(String storeName) { this.storeName = storeName; } }   In the end, the overall application will look like Figure 4-4. To run the application from the sources, deploy the WAR file distribution to your application server, and then load the following URL into your browser: http://your-server:port_number/JavaEERecipes/faces/chapter04/chapter04_01a.xhtml. Figure 4-4.  Application using Facelets template How It Works Applying a Facelets template to individual views within a JSF application is quite easy. Views that make use of a template are known as template clients. As mentioned in Recipe 4-1, a view template can specify individual ui:insert tags, along with the name attribute, in any location on the template where view content could be inserted. The name attribute within the ui:insert tag will pair up with the name attribute within the ui:define tag in the template client in order to determine what content is inserted. Note■■ as noted in Recipe 4-1, each view that uses a Facelets template can be referred to as a composition. It can also be referred to as a template client. It is important to note that a template client, or composition, contains an opening and closing tag. Everything outside of those tags is actually ignored at rendering time because the template body is used instead. You can also omit the tags within a template client and just open and close the view using the tags instead. Please see the “Opening/Closing Template Clients with ” sidebar for an example. Chapter 4 ■ Facelets 172 Opening/Closing Template Clients with   It is common to see template client views using opening and closing tags, as demonstrated with the example views in the solution to this recipe. However, since everything outside of the tags is ignored at rendering time, you can omit those tags completely. It is sometimes useful to open and close a template client with the tag. However, some page editors will be unable to work with the code or errors will be displayed because the view does not include the element at its root. Here’s an example of using as the opening and closing elements of a template client:     <>     Use the technique that suits your application the best! Remember, JSF and Facelets will treat each view the same, and you can save a few lines of code specifying as the root. Applying Templates A template can be applied to a view by specifying it within the template attribute within the view’s ui:composition tag. For instance, all the views within this example specify the same template, as you can see in the following excerpt:     The name of the template in the example is custom_template.xhtml, and the path to the template is ./layout/. The ui:composition tag should encapsulate all other markup within a Facelets view. All views that are to use the template must specify the ui:composition tag. A number of other useful Facelets template tags come along with Facelets, as described in Table 4-1. Table 4-1.  Facelets Page Control and Template Tags Tag Description ui:component Defines a template component and specifies a file name for the component ui:composition Defines a page composition and encapsulates all other JSF markup ui:debug Creates a debug component, which captures debugging information, namely, the state of the component tree and the scoped variables in the application, when the component is rendered ui:define Defines content that is inserted into a page by a template ui:decorate Decorates pieces of a page ui:fragment Defines a template fragment, much like ui:component, except that all content outside of tag is not disregarded (continued) Chapter 4 ■ Facelets 173 The ui:define tag encloses content that will be inserted into the template at the location of the template’s ui:insert tags. The ui:define tag is matched to a template’s ui:insert tag based on the value of the name attribute that is common to each tag. As you can see from the first view listing in this example, the first ui:define tag specifies top for the name attribute, and this will correspond to the template ui:insert tag with a name attribute equal to top. But the template does not specify such a tag! That is OK; there does not have to be a one-to-one match between the ui:define and ui:insert tags. A view can specify any number of ui:define tags, and if they do not correspond to any of the ui:insert tags within the template, then they are ignored. Likewise, a template can specify any number of ui:insert tags, and if they do not correspond to a ui:define tag within the template client view, then the content that is defined within the template in that location will be displayed. Looking at the same view, another ui:define tag contains a name attribute value equal to content, and this tag does correspond with a ui:insert tag within the template that also has a name attribute value of content. The following excerpt is taken from the template, and it shows the ui:insert tag that corresponds to the view’s ui:define tag with the same name attribute. You can see the full listing for the template in Recipe 4-1.  
Content
  The following excerpt, taken from recipe04_01a.xhtml, is the corresponding ui:define tag that will be inserted into the template at this location:  

Author List for Java 7 Recipes

Below is the list of authors. Click on the author's last name for more information regarding the author.


Java 7 Recipes Authors Tag Description ui:include Allows another XHTML page to be encapsulated and reused within a view ui:insert Inserts content into a template ui:param Passes parameters to an included file or template ui:repeat Iterates over a collection of data ui:remove Removes content from a page Table 4-1.  (continued) Chapter 4 ■ FaCelets 174

As you can see, it can be very powerful to define a view template that can be applied to several views within an application. Facelets templating provides a very powerful solution for defining such a template, allowing for consistent page layout and reusable page code. 4-3. Ensuring Resource Availability from All Views Problem You want to include resources, such as CSS, images, and JavaScript code, within your views that are accessible for use from every view within your application. For instance, rather than hard-coding a URL to an image, you want to reference the image location and have the application dynamically create the URL to the image location at runtime. Solution Create a resource directory and, optionally, subfolders within the resources directory to contain the resources that your application will utilize. Any CSS files, images, and so on, that are placed within subdirectories in the resources folder can be referenced within a JSF view via a JSF component’s library attribute, rather than specifying the full path to the resource. In the following example, a cascading style sheet is used to style the table of authors within the application. For this recipe, you will use the styles.css sheet that was applied to the h:dataTable in Recipe 3-12. The style sheet declaration will reside within the custom_template.xhtml template, and you will use an h:outputStylesheet component rather than a tag. As a matter of fact, all of the tags will be removed and replaced with h:outputStylesheet components to take advantage of the resources folder. The directory structure should look like Figure 4-5 when set up correctly. Figure 4-5. Utilizing the resources directory Chapter 4 ■ Facelets 175 The following listing is the updated custom_template.xhtml, because it now utilizes the h:outputStylesheet component rather than the tag. Note that the library attribute is specified as css.   #{faceletsAuthorController.storeName}

#{faceletsAuthorController.storeName}

Java 7 Recipes

Java EE 7 Recipes
Content
Written by Josh Juneau, Apress Author
    i Chapter 4 ■ Facelets 176 The h:dataTable component that is used to list the authors within the views of the Acme Bookstore application can now make use of the styles that are listed within styles.css. The following excerpt from the XHTML document named recipe04_03.xhtml demonstrates the h:dataTable component with the styles applied:   Java 7 Recipes Authors   The table should now look like Figure 4-6 when rendered on a page. Figure 4-6.  Author table with styles applied Chapter 4 ■ Facelets 177 How It Works It is easy to add a resource to a JSF application because there is no need to worry about referring to a static path when declaring the resources. Since the release of JSF 2.0, the resources folder can be used to list subfolders, also known as libraries, into which the resources can be placed. The JSF components that can use resources now have the library attribute baked into them. This allows a specific library to be specified for such components so that the component will know where to find the resources that it requires. To use the new resources folder, create a folder at the root of an application’s web directory and name it resources. That resources folder can then contain subfolders, which will become the libraries that can be utilized within the JSF components. For instance, subfolders can be named css and images, and then those names can be specified for the library attribute of JSF components that utilize such resources. In the example, cascading style sheets are placed into the resources/css folder, and then they are referenced utilizing the h:outputStylesheet component and specifying the css library as follows:     Other resources can be placed within such libraries. The h:graphicImage component also contains the library attribute, so the images for the books can be moved into a folder named resources/image, and then the h:graphicImage tag can reference the image as such:     It has always been a challenge referencing resource files from the pages of a web application. To do so, a developer needs to know the exact path to the resource, and sometimes the path can be broken if folder names are changed or if the application is deployed in a different server environment. The use of the resources folder in JSF 2.0 along with the new library attribute has greatly reduced the complexity of managing such resources. 4-4. Creating Reusable Templates That Act As Components Problem You want to encapsulate a component along with its validator and styling so that it can be reused in any JSF view within your application. Solution Create a new XHTML document that includes namespace declarations as required for use of the Facelets and JSF components, along with the Facelets tags required to create a composite component. The document can contain any valid JSF components or HTML markup needed to develop the component you desire. The Facelets tags that can be used to help develop composite components are and . Any attributes that a component will accept will be declared within the element, and the actual component implementation will be declared within the element. The component can then be used within another JSF view by declaring the namespace to the component XHTML document and then adding the component tag to the view. Let’s take a look at an example. The example in this recipe contains a handful of source listings, each of which is required to construct and utilize the composite component. In this example, you’ll create a component that will act as a search mechanism for authors who have books within the Acme Bookstore. A user will be able to type the name of an author in order to search for their bio. The search component will include an h:inputText component for accepting the search Chapter 4 ■ Facelets 178 text, an h:commandButton for submitting the search text to the managed bean, and an h:outputText component for displaying a message if the search is unsuccessful. The component will utilize its own JSF managed bean for providing the business logic that is required to perform the search activity. Once the component construction is completed, a simple JSF tag can be added to any page in order to include said search component. Creating the Composite Component: search.xhtml You’ll start by taking a look at the source for the composite component itself. The following code is for an XHTML document entitled search.xhtml, and it declares the composite component layout. The file should be saved into the resources folder within a JSF application, and for this example it is saved in the folder resources/components/util.   < composite:interface> < composite:attribute name="searchAction" default="#{searchController.searchAuthors (completeAuthorController.completeAuthorList)}" method-signature="java.lang.String action(java.util.List)"/> < composite:implementation>
  Managed Bean Controller for Composite Component: SearchController.java Next, let’s look at the code for the JSF managed bean that is used for containing the business logic used for the component. The bean class is named SearchController.   package org.javaeerecipes.chapter04.recipe04_04;   import javax.faces.bean.RequestScoped; import javax.faces.bean.ManagedBean; import javax.faces.bean.ManagedProperty; import org.javaeerecipes.chapter04.recipe04_01.Author;   Chapter 4 ■ Facelets 179 /** * Recipe 4-4 * @author juneau */ @ManagedBean(name = "searchController") @RequestScoped public class SearchController implements java.io.Serializable {   private String searchText; private String errorText;   @ManagedProperty(value="authorController") private AuthorController authorController;   /** * Creates a new instance of SearchController */ public SearchController() {   }   public String searchAuthors(List authorList){ String fullName = null; String returnString = null;   for (Author author: authorList){ fullName = author.getFirst() + " " + author.getLast(); if (author.getFirst().equalsIgnoreCase(searchText)){ returnString = getAuthorController().displayAuthor(author.getLast()); } else if (author.getLast().equalsIgnoreCase(searchText)){ returnString = getAuthorController().displayAuthor(author.getLast()); } else if (fullName.equalsIgnoreCase(searchText)){ returnString = getAuthorController().displayAuthor(author.getLast()); } } if(returnString == null){ setErrorText("No Author Found"); returnString = "recipe04_04a"; } return returnString; }   /** * @return the searchText */ public String getSearchText() { return searchText; }   Chapter 4 ■ Facelets 180 /** * @param searchText the searchText to set */ public void setSearchText(String searchText) { this.searchText = searchText; }   /** * @return the authorController */ public AuthorController getAuthorController() { return authorController; }   /** * @param authorController the authorController to set */ public void setAuthorController(AuthorController authorController) { this.authorController = authorController; }   /** * @return the errorText */ public String getErrorText() { return errorText; }   /** * @param errorText the errorText to set */ public void setErrorText(String errorText) { this.errorText = errorText; } }  Managed Bean Controller: AuthorController.java Note that the managed bean contains an annotation, @ManagedProperty, which has not yet been covered up to this point in the book. I’ll discuss that annotation a bit in the following section. Also note that in the composite component document, search.xhtml, another managed bean is referenced by the name of completeAuthorController. This managed bean is essentially the same as the JSF managed bean that was constructed in Recipe 4-1, with an added List declaration named completeAuthorList. This List is used to contain all of the Author objects for those who have books listed in the Acme Bookstore. The source listing for the updated AuthorContoller managed bean is as follows:   package org.javaeerecipes.chapter04.recipe04_04;   import org.javaeerecipes.chapter04.recipe04_01.*; import java.io.Serializable; import java.util.ArrayList; import java.util.List; Chapter 4 ■ Facelets 181 import javax.annotation.ManagedBean; import javax.enterprise.context.SessionScoped; import javax.inject.Named;   /** * Recipe 4-4 * * @author juneau */ @Named(value = "completeAuthorController") @SessionScoped @ManagedBean public class AuthorController implements Serializable {   private List authorList; private List completeAuthorList private String storeName = "Acme Bookstore";   private String juneauBio = "Josh Juneau has been developing software" + " since the mid-1990s. PL/SQL development and database programming" + " was the focus of his career in the beginning, but as his skills developed," + " he began to use Java and later shifted to it as a primary base for his" + " application development. Josh has worked with Java in the form of graphical" + " user interface, web, and command-line programming for several years. " + "During his tenure as a Java developer, he has worked with many frameworks" + " such as JSF, EJB, and JBoss Seam. At the same time, Josh has extended his" + " knowledge of the Java Virtual Machine (JVM) by learning and developing applications" + " with other JVM languages such as Jython and Groovy. His interest in learning" + " new languages that run on the JVM led to his interest in Jython. Since 2006," + " Josh has been the editor and publisher for the Jython Monthly newsletter. " + "In late 2008, he began a podcast dedicated to the Jython programming language."; private String deaBio = "This is Carl Dea's Bio"; private String beatyBio = "This is Mark Beaty's Bio"; private String oConnerBio = "This is John O'Connor's Bio"; private String guimeBio = "This is Freddy Guime's Bio"; private Author current; private String authorLast;   /** * Creates a new instance of RecipeController */ public AuthorController() { populateJavaRecipesAuthorList(); populateCompleteAuthorList();   }   public String populateJavaRecipesAuthorList() {   authorList = new ArrayList (); authorList.add(new Author("Josh", "Juneau", juneauBio)); Chapter 4 ■ Facelets 182 authorList.add(new Author("Carl", "Dea", deaBio)); authorList.add(new Author("Mark", "Beaty", beatyBio)); authorList.add(new Author("John", "O'Conner", oConnerBio)); authorList.add(new Author("Freddy", "Guime", guimeBio)); return "recipe04_04a"; }   public String populateJavaEERecipesAuthorList() { System.out.println("initializng authors list"); authorList = new ArrayList (); authorList.add(new Author("Josh", "Juneau", juneauBio)); return "recipe04_04b";   }   private String populateCompleteAuthorList() {   setCompleteAuthorList(null);   setCompleteAuthorList(new ArrayList ()); getCompleteAuthorList().add(new Author("Josh", "Juneau", juneauBio)); getCompleteAuthorList().add(new Author("Carl", "Dea", deaBio)); getCompleteAuthorList().add(new Author("Mark", "Beaty", beatyBio)); getCompleteAuthorList().add(new Author("John", "O'Conner", oConnerBio)); getCompleteAuthorList().add(new Author("Freddy", "Guime", guimeBio)); return "recipe04_04a"; }   public String displayAuthor(String last) { for (Author author : authorList) { if (author.getLast().equals(last)) { current = author; } } return "recipe04_04c"; }   /** * @return the authorList */ public List getauthorList() { return authorList; }   /** * @return the current */ public Author getCurrent() { return current; }   Chapter 4 ■ Facelets 183 /** * @param current the current to set */ public void setCurrent(Author current) { this.current = current; }   /** * @return the authorLast */ public String getAuthorLast() { return authorLast; }   /** * @param authorLast the authorLast to set */ public void setAuthorLast(String authorLast) { displayAuthor(authorLast); }   /** * @return the storeName */ public String getStoreName() { return storeName; }   /** * @param storeName the storeName to set */ public void setStoreName(String storeName) { this.storeName = storeName; }   /** * @return the completeAuthorList */ public List getCompleteAuthorList() { return completeAuthorList; }   /** * @param completeAuthorList the completeAuthorList to set */ public void setCompleteAuthorList(List completeAuthorList) { this.completeAuthorList = completeAuthorList; } }   Chapter 4 ■ FaCelets 184 Utilizing the Composite Component: custom_template_search.xhtml Now that all of the necessary sources have been written for the component, it can be utilized within a page. The Acme Bookstore would like to have the search component displayed at the top of each page, so you’ll add it to the site template that was created in Recipe 4-1. The following code shows the updated markup for the template, and it has been saved into an XHTML document named custom_template_search.xhtml in the same folder as the original template: #{faceletsAuthorController.storeName}

#{faceletsAuthorController.storeName}


Java 7 Recipes

Java EE 7 Recipes
Content
Chapter 4 ■ Facelets 185
Written by Josh Juneau, Apress Author
    The search component is added to the template using the tag , and it will now appear at the top of each page within the Acme Bookstore application. Figure 4-7 shows what the updated store application looks like. Figure 4-7.  Acme bookstore layout with search component Note■■ as of the release of JSF 2.2 with Java EE 7, it is possible to create composite components using Java code only with no markup. How It Works Creating JSF components has been a boon for the JSF technology because it allows portions of web views to be saved and reused in many places. The problem is that creating JSF components has always been a bit of a daunting task because there is quite a bit of work required to develop custom JSF components. However, when JSF 2.0 came about, the Facelets view definition language was baked in, and it included the ability to save portions of JSF views into their own components by utilizing the Facelets ui:component tag. Such components are referred to Chapter 4 ■ Facelets 186 as composite components. Composite components are easy to develop and include most of the functionality that is required for standard application use. The development of composite components consists of the creation of a separate XHTML document to contain the composite component layout, as well as an optional managed bean controller for containing any business logic that the composite component requires. In the example, an XHTML document entitled search.xhtml contains the layout for the composite component. The Facelets view definition language contains a handful of tags that can be useful for developing composite components. To use them, the required namespace must be declared within the composite component XHTML document. The following code excerpt from the search.xhtml document shows the declaration:     Note■■   JSF views that use composite components are referred to as using views. As specified in the example namespace declaration, a prefix, such as composite, can be used to reference the Facelets tags for creating composite components by declaring the prefix in the namespace. As such, the composite:interface and composite:implementation tags are useful for developing composite components, and they are used in the example. The composite:interface tag is optional as of JSF 2.2, and it can be used to specify any attributes that the component should be able to accept. In the example, an attribute by the name of searchAction is declared within the composite:interface elements. This attribute contains a default value and a method-signature, and it can be specified within a using view to override the default implementation method for the search component. Since the attribute specifies a default value, it is not required for the component’s use within a view.     Any number of attributes can be declared for a component, and if the attribute is used to specify a value rather than a method, then the method-signature attribute for the composite:interface tag does not have to be present. For instance, to declare an attribute that accepts a particular value for the name of a label, you may include an attribute such as the following:     The implementation for a composite component should be defined between opening and closing composite:implementation tags. The composite component in the example includes an h:form that will be used to submit search text to the SearchController managed bean. The composite component implementation also includes three JSF components: h:inputText to accept the search text, h:commandButton to invoke the searchAuthors method, and h:outputText to display a message if the search fails.  
  Chapter 4 ■ Facelets 187
  The action that is specified for the h:commandButton is #{cc.attrs.searchAction}, and this corresponds to the searchAction attribute that was defined within the composite:interface element within the composite component view. Any attribute that is defined within the view can be referenced using the cc.attrs prefix. The word cc in JavaServer Faces is a reserved identifier for use with composite components. The cc.attrs identifier can be used to access composite component attributes. The default method that will be specified for the searchAction attribute in the example is #{searchController.searchAuthors}, but a using view can specify another method if needed. The value for both the h:inputText and h:outputText components within the composite component implementation are properties that are exposed from the SearchController managed bean class. The SearchController managed bean class encapsulates the business logic for the search component. Within the class, an @ManagedProperty annotation is specified. The @ManagedProperty annotation is used to inject a value into the annotated property. In the example, the AuthorController managed bean is injected, so now any of the public fields or methods contained within AuthorController can be utilized from within the SearchController managed bean. The properties searchText and errorText are declared within the bean, and they are used within the component for setting the search text and displaying an error message, respectively. When the composite component’s h:commandButton is clicked, the searchAuthors method is invoked, passing the complete list of authors, completeAuthorList, from the AuthorController managed bean. Taking a look at the method, it goes through each Author object within the complete author list and evaluates whether the searchText matches either the first, last, or full name of any author. If so, the AuthorController’s displayAuthor method is invoked, passing the last field for the matching Author object, returning a String for the view name that should be rendered next. If the searchText does not match any of the Author objects, then the errorText property is populated with an error message, and the view named recipe04_04a.xhtml is displayed. To use the composite component within a view, the XML namespace for the composite component must be declared and assigned a prefix. After doing so, the name of the composite component XHTML document should be specified as the tag name, followed by any attributes that are required. In the example, the namespace is declared as follows:     The composite component can then be utilized within the page as follows:     Developing components for use within JSF applications has never been easier. The Facelets ui:component tag has certainly made component creation much easier on developers and allows for the reuse of view fragments throughout JSF applications. 4-5. Handling Variable-Length Data on a Page Problem You are interested in iterating over a collection of data using a technique other than an h:dataTable component because you want to use standard HTML table markup for each row and column of the table. Chapter 4 ■ Facelets 188 Solution Use the Facelets ui:repeat tag for iterating over a collection of data rather than the h:dataTable component. Doing so allows for the same style of collection iteration, but it does not force the use of the h:dataTable component elements. For this recipe, the Acme Bookstore application has been rewritten so that it now contains the ability to list each author’s books separately on their bio page. When an author name is chosen from the book listing or when an author is searched, then the bio page will appear, and the author’s bio is displayed along with each of the books that the author has written. Note■■ the example for this recipe has been rewritten to make the application more robust. A new Book class has been created so that each book is now its own object. The Author class has been rewritten so that one or more Book objects can now be added to each Author object. The AuthorController has been rewritten so that the new Book and Author objects can be used to populate the author listing tables, and a new method has been added that allows for the initialization of each Book and Author object. To use the new classes, the application template (custom_template_neworg.xhtml), search component (search_neworg.xhtml), and each of the application views (recipe04_05a.xhtml, recipe04_05b.xhtml, recipe04_05c.xhtml) have been rewritten. Please refer to the sources in the org.javaeerecipes.chapter04.recipe04_05 package and the recipe’s corresponding XHTML documents for complete listings. The ui:repeat tag is used to iterate over a collection of the selected author’s books within the author bio view, named recipe04_05c.xhtml. The author bio page can be reached by selecting an author from a listing of authors or searching for an author using the search component. The following code shows the view, recipe04_05c.xhtml, which is the bio view:   Recipe 4-5: Facelets Page Template

#{uiRepeatAuthorController.current.first} #{uiRepeatAuthorController.current.last}

Chapter 4 ■ Facelets 189

#{uiRepeatAuthorController.current.bio}


Author's Books

#{book.title}
  Each Author object contains a list of books that an author has written, and when the bio page is rendered, it looks like Figure 4-8, displaying the list of books that the author has written using the ui:repeat tag. Chapter 4 ■ Facelets 190 How It Works The Facelets ui:repeat tag is a nice alternative to the h:dataTable component if you need to have more control over the HTML table that is rendered. The h:dataTable component is powerful in that it makes it easy to iterate over a collection of objects and display them within a page. However, sometimes it is useful to control the layout a bit more, and ui:repeat provides that level of control. The ui:repeat tag has a handful of attributes that need to be specified in order to bind the tag to a collection of data within a managed bean. Specifically, the value and var attributes, much like those of the h:dataTable component, are used to specify the collection to iterate over and the variable that will be used to refer to a single object within the collection, respectively. In the example, the value attribute is set to #{uiRepeatAuthorController.current.books}, which is a collection of Book objects that is attached to the currently selected Author, and the var attribute is set to the value book. The markup and JSF tags placed between the opening and closing ui:repeat tags will be processed for each iteration over the collection of objects. In the example, two table rows are placed inside ui:repeat; one row contains the book cover image, and the other contains the name of the book. The Book object fields are referenced within ui:repeat using the value of the var attribute, book. Figure 4-8.  Displaying a collection of objects with ui:repeat Chapter 4 ■ Facelets 191 In the example for this recipe, the views that display the complete author list for each of the books use a List named authorList. The authorList is declared within the AuthorController managed bean and populated with Author objects. When an author is selected from the list, the displayAuthor method within AuthorController is invoked, which populates the current Author object. Let’s take a look at the AuthorController for this recipe, which has been rewritten since its use within previous recipes.   package org.javaeerecipes.chapter04.recipe04_05;   import org.javaeerecipes.chapter04.recipe04_04.*; import org.javaeerecipes.chapter04.recipe04_01.*; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.annotation.ManagedBean; import javax.enterprise.context.SessionScoped; import javax.inject.Named;   /** * Recipe 4-5 * * @author juneau */ @Named(value = "uiRepeatAuthorController") @SessionScoped @ManagedBean public class AuthorController implements Serializable {   private List authorBookList; private List authorList; private List completeAuthorList; private String storeName = "Acme Bookstore";   private String juneauBio = "Josh Juneau has been developing software" + " since the mid-1990s. PL/SQL development and database programming" + " was the focus of his career in the beginning, but as his skills developed," + " he began to use Java and later shifted to it as a primary base for his" + " application development. Josh has worked with Java in the form of graphical" + " user interface, web, and command-line programming for several years. " + "During his tenure as a Java developer, he has worked with many frameworks" + " such as JSF, EJB, and JBoss Seam. At the same time, Josh has extended his" + " knowledge of the Java Virtual Machine (JVM) by learning and developing applications" + " with other JVM languages such as Jython and Groovy. His interest in learning" + " new languages that run on the JVM led to his interest in Jython. Since 2006," + " Josh has been the editor and publisher for the Jython Monthly newsletter. " + "In late 2008, he began a podcast dedicated to the Jython programming language."; private String deaBio = "This is Carl Dea's Bio"; private String beatyBio = "This is Mark Beaty's Bio"; private String oConnerBio = "This is John O'Connor's Bio"; private String guimeBio = "This is Freddy Guime's Bio"; private Author current; private String authorLast;   Chapter 4 ■ Facelets 192 /** * Creates a new instance of RecipeController */ public AuthorController() { populateAuthors(); populateJavaRecipesAuthorList(); populateCompleteAuthorList(); }   private void populateAuthors(){   Book book1 = new Book("Java 7 Recipes", "java7recipes.png"); Book book2 = new Book("Java EE 7 Recipes", "javaEE 7recipes.png"); Book book3 = new Book("Java FX 2.0: Introduction By Example", "javafx.png"); authorBookList = new ArrayList ();   Author author1 = new Author("Josh", "Juneau", juneauBio); author1.addBook(book1); author1.addBook(book2); authorBookList.add(author1);   Author author2 = new Author("Carl", "Dea", deaBio); author2.addBook(book1); author2.addBook(book3); authorBookList.add(author2);   Author author3 = new Author("Mark", "Beaty", beatyBio); author3.addBook(book1); authorBookList.add(author3);   Author author4 = new Author("John", "O'Conner", oConnerBio); author4.addBook(book1); authorBookList.add(author4);   Author author5 = new Author("Freddy", "Guime", guimeBio); author5.addBook(book1); authorBookList.add(author5); }   /** * Searches through all Author objects and populates the authorList * with only those authors who were involved with the Java 7 Recipes book * @return */ public String populateJavaRecipesAuthorList() { authorList = new ArrayList<>(); for(Author author:authorBookList){ Listbooks = author.getBooks(); for(Book book:books){ Chapter 4 ■ Facelets 193 if(book.getTitle().equals("Java 7 Recipes")){ authorList.add(author); } } }   return "recipe04_05a"; }   /** * Searches through all Author objects and populates the authorList * with only those authors who were involved with the Java EE 7 Recipes book * @return */ public String populateJavaEERecipesAuthorList() { authorList = new ArrayList<>(); for(Author author:authorBookList){ Listbooks = author.getBooks(); for(Book book:books){ if(book.getTitle().equals("Java EE 7 Recipes")){ authorList.add(author); } } } return "recipe04_05b";   }   /** * Populates completeAuthorList with each existing Author object * @return */ private void populateCompleteAuthorList() { completeAuthorList = new ArrayList(); for(Author author:authorBookList){ completeAuthorList.add(author); }   }   public String displayAuthor(String last) { for (Author author : authorList) { if (author.getLast().equals(last)) { current = author; } } return "recipe04_05c"; }   Chapter 4 ■ FaCelets 194 /** * @return the authorList */ public List getauthorList() { return authorList; } /** * @return the current */ public Author getCurrent() { return current; } /** * @param current the current to set */ public void setCurrent(Author current) { this.current = current; } /** * @return the authorLast */ public String getAuthorLast() { return authorLast; } /** * @param authorLast the authorLast to set */ public void setAuthorLast(String authorLast) { displayAuthor(authorLast); } /** * @return the storeName */ public String getStoreName() { return storeName; } /** * @param storeName the storeName to set */ public void setStoreName(String storeName) { this.storeName = storeName; } /** * @return the completeAuthorList */ Chapter 4 ■ Facelets 195 public List getCompleteAuthorList() { return completeAuthorList; }   /** * @param completeAuthorList the completeAuthorList to set */ public void setCompleteAuthorList(List completeAuthorList) { this.completeAuthorList = completeAuthorList; } }   When displayAuthor is invoked, the current Author object is populated with the currently selected author, and the bio page is rendered. The bio page source is listed in the solution to this recipe. Each Author object contains a List of Book objects that correspond to the books that particular author has written. The ui:repeat tag is used to iterate over this list of books. The ui:repeat tag can be effective in various use cases. When deciding to use h:dataTable or ui:repeat, it is best to determine whether customization is going to be imperative. For those situations where more control is desired, ui:repeat is certainly the best choice. 4-6. Debugging View Content Problem You are running into view issues and want to perform some debugging on your view layout. Solution Insert the ui:debug tag into the JSF view that you want to debug. One of the JSF views for the Acme Bookstore has been rewritten to include the ui:debug tag. The source for the view is as follows:       Chapter 4 ■ Facelets 196

Author List for Java 7 Recipes

Below is the list of authors. Click on the author's last name for more information regarding the author.


Java 7 Recipes Authors

    Once the view has been rendered in a browser, pressing the Ctrl+Shift+D keys will bring up a debug window for the page that looks like Figure 4-9. Figure 4-9.  The ui:debug output window Chapter 4 ■ Facelets 197 How It Works Debugging JSF views can sometimes prove to be frustrating, especially if there is an issue within some JSF EL within the view. Facelets provides a convenient tool known as ui:debug that helps satisfy the requirement of debugging troubled JSF views. To use the tool, add the ui:debug tag to the JSF view that you want to debug. In most environments, it can be most useful to add the tag to the application template so that each template client view inherits the tag. When the view is rendered in a browser, press the Ctrl+Shift+D keys to open the debug window for the view. The debug window contains a lot of information regarding the current state of the component tree, as well as the scoped variables within the application. The ui:debug tag contains a rendered attribute that can be used to determine when the tag should be included in the view. For instance, an EL expression can be used for the rendered attribute to signify whether the environment is in development or production, returning a Boolean value that either renders the tag or not. The ui:debug tag also includes a hotkey attribute, which can be used to change the key that is pressed along with Ctrl+Shift in order to open the debug window. By default, the hot key is D, which stands for “debug.” 4-7. Writing a Custom Resolver for Locating Facelets Templates and Resources Problem You want to enable your application to have the ability to locate Facelets resource files from an external JAR. This would allow you to package all resources within a single JAR that could be used by a suite of your applications. Solution Package your resources into a JAR file or WAR file, and then write a custom ResourceResolver class to locate those resources. FacesServlet will then use the custom resolver class to find the Facelets files you request. The following source listing, for a class named FaceletsResourceResolver, can be used to resolve the URL to the resource you require rather than using the native Facelets ResourceResolver.   package org.javaeerecipes.chapter04.recipe04_07;    import java.net.URL; import javax.faces.view.facelets.ResourceResolver; /** * Recipe 4-7 * @author juneau */ @FaceletsResourceResolver public class FaceletsResourceResolver extends ResourceResolver {   private ResourceResolver parent;   public FaceletsResourceResolver(ResourceResolver parent) { this.parent = parent; }   Chapter 4 ■ Facelets 198 @Override public URL resolveUrl(String path) { System.out.println("Resolving URL " + path); URL url = parent.resolveUrl(path); if (url == null) {   if (path.startsWith("/")) { path = path.substring(1); } url = Thread.currentThread().getContextClassLoader(). getResource(path); } return url; }   }   When the application is redeployed, the new FaceletsResourceResolver class will be used to resolve the URL for accessing resources, rather than the default resolver. How It Works Sometimes it makes sense to package resources into a JAR or WAR file so that they can be shared across multiple applications or with a number of different developers. The problem is that simply adding the JAR or WAR file to the application CLASSPATH will not allow for such resources to become accessible to the application. You must write a custom resource resolver in order to find the path to the custom resource, rather than relying upon the default resolver. To write a resolver class, extend the ResourceResolver abstract class, and override the resolveUrl(String) method with the custom resolver implementation. The custom implementation should search the CLASSPATH for the resource and return a URL that corresponds to the resource’s location. To register the resolver with Facelets, you can annotate the class using the @FaceletsResourceResolver annotation or modify the web.xml deployment descriptor (as described in the following note). Note■■ prior to JSF 2.2, a Facelets ResourceResolver had to be manually configured within the web.xml ­deployment descriptor. The ability to annotate the class with the @FaceletsResourceResolver was a new feature of Java EE 7 and JSF 2.2. It is good to note that if you have a resource resolver defined via an annotation and also via web.xml, the resolver defined within the web.xml file will take precedence. If you are using JSF 2.1 or earlier, then to manually configure the ResourceResolver for the example in this recipe, place the following lines of XML into the web.xml deployment descriptor: facelets.RESOURCE_RESOLVER org.javaeerecipes.chapter04.recipe04_07.FaceletsResourceResolver 199 Chapter 5 JavaServer Faces Standard Components The JSF framework allows developers to build applications utilizing a series of views, and each view consists of a series of components. The framework is kind of like a puzzle in that each piece must fit into its particular place in order to make things work smoothly. Components are just another piece of the puzzle. Components are the building blocks that make up JSF views. One of the strengths of using the JSF framework is the abundance of components that are available for use within views. To developers, components can be tags that are placed within the XHTML views. Components resemble standard HTML tags; they contain a number of attributes, an opening tag and a closing tag, and sometimes components that are to be embedded inside of others. Components can also be written in Java code, and their tags can be bound to Java code that resides within a JSF managed bean. A number of components come standard with the JSF framework. The recipes in this chapter will cover the standard components in detail, and it will provide examples that will allow you to begin using components in your applications right away. This chapter focuses on the JSF standard component library, and toward the end it features some recipes showing how to use external component libraries. The example in this chapter will grow from the first recipe throughout each recipe to the final recipe. In the end, a newsletter page for the Acme Bookstore will be complete and full-featured. Before tackling the recipes, though, the following section provides a brief overview of the standard JSF components and associated common component tags. This will help you get the most out of the recipes. Component and Tag Primer Table 5-1 lists the components that are available with a clean install of the JSF framework. Table 5-1.  JSF HTML Components Component Tag Description UIColumn h:column Represents a column of data in the dataTable component UICommand h:commandButton Submits a form h:commandLink Links pages or actions UIData h:dataTable Represents a table used for iterating over collections of data UIForm h:form Represents an input form (continued) Chapter 5 ■ JavaServer Faces Standard Components 200 Component Tag Description UIGraphic h:graphicImage Displays an image UIInput h:inputHidden h:inputSecret h:inputText h:inputTextarea Includes a hidden variable in a form Allows text entry without displaying the actual text Allows text entry Allows multiline text entry UIOutcomeTarget h:link Links to another page or location UIMessage h:message Displays a localized message UIMessages h:messages Displays localized messages UIOutput h:outputFormat h:outputLabel h:outputLink Displays a formatted localized message Displays a label for a specified field Links to another page or location UIPanel h:panelGrid h:panelGroup Displays a table Groups components UISelectBoolean h:selectBooleanCheckbox Displays a Boolean choice UISelectItem h:selectItem Represents one item in a list of items for selection UISelectItems h:selectItems Represents a list of items for selection UISelectMany h:selectManyCheckbox Displays a group of check boxes that allow multiple user choices h:selectManyListbox h:selectManyMenu Allows a user to select multiple items from a list Allows a user to select multiple items from a drop-down menu UISelectOne h:selectOneListbox h:selectOneMenu h:selectOneRadio Allows a user to select a single item from a list Allows a user to select a single item from a drop-down menu Allows a user to select one item from a set Table 5-1.  (continued) JSF provides a number of core tags that can be used to provide more functionality for the components. For example, these tags can be embedded inside JSF component tags and specify rules that can be used to convert the values that are displayed or used as input for the component. Other uses of the core tags are to provide a list of options for a select component, validate input, and provide action and event listeners. Table 5-2 describes the JSF core tags. Chapter 5 ■ JavaServer Faces Standard Components 201 Note■■ the common sources and the completed classes to run the application for Chapter 5 are contained within the org.javaeerecipes.chapter05 package, and one or more recipes throughout this chapter will utilize classes contained within that package. Common Component Tag Attributes Each standard JSF component tag contains a set of attributes that must be specified in order to uniquely identify it from the others, register the component to a managed bean, and so on. There is a set of attributes that are common across each component tag, and this section lists those attributes, along with a description of each. All attributes besides id can be specified as JSF EL. • binding: A managed bean property can be specified for this attribute, and it can be used to bind the tag to a component instance within a managed bean. Doing so allows you to programmatically control the component from within the managed bean. • id: This attribute can be set to uniquely identify the component. If you do not specify a value for the id attribute, then JSF will automatically generate one. Each component within a view must have a unique id attribute, or an error will be generated when the page is rendered. I recommend you specify a value for the id attribute on each component tag, because then it will Table 5-2.  JSF Core Tags Tag Function f:actionListener Registers an action listener method with a component f:phaseListener Registers a PhaseListener to a page f:setPropertyActionListener Registers a special form submittal action listener f:valueChangeListener Registers a value change listener with a component f:converter Registers an arbitrary converter with a component f:convertDateTime Registers a DateTimeConverter instance with a component f:convertNumber Registers a NumberConverter with a component f:facet Adds a nested component to particular enclosing parents f:metadata Registers a particular facet with a parent component f:selectItem Encapsulates one item in a list f:selectItems Encapsulates all items of a list f:validateDoubleRange Registers a DoubleRangeValidator with a component f:validateLength Registers a LengthValidator with a component f:validateLongRange Registers a LongRangeValidator with a component f:validator Registers a custom validator with a component f:validateRegex Registers a RegExValidator with a component (JSF 2.0) f:validateBean Delegates validation of a local value to a BeanValidator (JSF 2.0) f:validateRequired Ensures that a value is present in a parent component Chapter 5 ■ JavaServer Faces Standard Components 202 be easy to statically reference the tag from a scripting language or a managed bean if needed. If you let JSF automatically populate this attribute, it may be different each time, and you will never be able to statically reference the tag from a scripting language. • immediate: This attribute can be set to true for input and command components in order to force the processing of validations, conversions, and events when the request parameter values are applied. • rendered: The rendered attribute can be used to specify whether the component should be rendered. This attribute is typically specified as a JSF EL expression that is bound to a managed bean property yielding a Boolean result. The EL expression must be an rvalue expression, meaning that it is read-only and cannot set a value. • style: This attribute allows a CSS style to be applied to the component. The specified style will be applied when the component is rendered as output. • styleClass: This attribute allows a CSS style class to be applied to the component. The specified style will be applied when the component is rendered as output. • value: This attribute identifies the value of a given component. For some components, the value attribute is used to bind the tag to a managed bean property. In this case, the value specified for the component will be read from, or set within, the managed bean property. Other components, such as the commandButton component, use the value attribute to specify a label for the given component. Common JavaScript Component Tags Table 5-3 lists a number of attributes that are shared by many of the components, which enable JavaScript functionality to interact with the component. Table 5-3.  Common Component Atrributes Attribute Description onblur JavaScript code that should be executed when the component loses focus. onchange JavaScript code that should be executed when the component loses focus and the value changes. ondblclick JavaScript code that should be executed when the component has been clicked twice. onfocus JavaScript code that should be executed when the component gains focus. onkeydown JavaScript code that should be executed when user presses a key down and the component is in focus. onkeypress JavaScript code that should be executed when user presses a key and the component is in focus. onkeyup JavaScript code that should be executed when key press is completed and the component is in focus. onmousedown JavaScript code that should be executed when user clicks the mouse button and the component is in focus. onmouseout JavaScript code that should be executed when user moves mouse away from the component. onmouseover JavaScript code that should be executed when user moves mouse onto the component. (continued) Chapter 5 ■ JavaServer Faces Standard Components 203 Binding Components to Properties All JSF components can be bound to managed bean properties. Do so by declaring a property for the type of component you want to bind within the managed bean and then by referencing that property using the component’s binding attribute. For instance, the following dataTable component is bound to a managed bean property and then manipulated from within the bean. In the view:     In the bean:   // Provide getter and setter methods for this property private javax.faces.component.UIData myTable; . . . myTable.setRendered(true); . . .   Binding can prove to be very useful in some cases, especially when you need to manipulate the state of a component programmatically before re-rendering the view. 5-1. Creating an Input Form Problem You want to add input fields to a form within your application. Solution Create an input form by enclosing child input components within a parent form component. There are four JSF components that will allow for text entry as input. Those components are inputText, inputSecret, inputHidden, and inputTextarea. Any or all of these components can be placed within a form component in order to create an input form that accepts text entry. In the example for this recipe, you will create an input form that will be used to sign up for the Acme Bookstore newsletter. The user will be able to enter their first and last names, an e-mail address, a password, and a short description of their interests. Attribute Description onmousemove JavaScript code that should be executed when user moves mouse within the component. onmouseup JavaScript code that should be executed when mouse button click is completed and the component is in focus. onselect JavaScript code that should be executed when the component is selected by user. Table 5-3.  (continued) Chapter 5 ■ JavaServer FaCeS Standard ComponentS 204 The View: recipe05_01.xhtml The following code is for the view recipe05_01.xhtml, which constructs the layout for the input form:

Subscribe to Newsletter

Enter your information below in order to be added to the Acme Bookstore newsletter.









Chapter 5 ■ JavaServer Faces Standard Components 205 
    Note■■ as you can see from the example, HTML can be mixed together with JSF component tags. An HTML label tag is used to specify a label for each input component in this recipe. In Recipe 5-3, you will learn about the JSF component that is used to render a label. To learn more about how the commandButton component works, please see Recipe 5-2. Managed Bean: ContactController.java Each view that contains an input form needs to have an associated managed bean, right? The managed bean in this case is RequestScoped, and the name of the bean class is ContactController. The listing for the ContactController class is as follows:   package org.javaeerecipes.chapter05.recipe05_01;    import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.faces.application.FacesMessage; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.event.ValueChangeEvent; import javax.faces.model.SelectItem; import javax.faces.validator.ValidatorException; import javax.inject.Inject;   /** * Chapter 5 * * @author juneau */ @RequestScoped @ManagedBean(name = "contactController") Chapter 5 ■ JavaServer Faces Standard Components 206 public class ContactController implements java.io.Serializable {   private Contact current;   /** * Creates a new instance of ContactController */ public ContactController() {   }   /** * Obtain the current instance of the Contact object * @return Contact */ public Contact getCurrent(){ if (current == null){ current = new Contact(); } return current; }   /** * Adds a subscriber to the newsletter * @return String */ public String subscribe(){ // No implementation yet, will add to a database table in Chapter 7 FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Successfully Subscribed to Newsletter for " + getCurrent().getEmail(), null); FacesContext.getCurrentInstance().addMessage(null, facesMsg); return "SUBSCRIBE"; }   /** * Navigational method * @return String */ public String add(){ return "ADD_SUBSCRIBER"; } }  Note■■ at this time, nothing happens when the submit button is clicked other than a nice “Success” message being displayed on the screen. Later in the book, you will revisit the subscribe method and add the code for creating a record within an underlying database. The input screen should look like Figure 5-1 when rendered. Chapter 5 ■ JavaServer Faces Standard Components 207 How It Works The JavaServer Faces framework ships with a slew of standard components that can be utilized within JSF views. There are four standard components that can be used for capturing text input: inputText, inputSecret, inputHidden, and inputTextarea. These component tags, as well as all of the other standard JSF component tags, share a common set of attributes and some attributes that are unique to each specific tag. To learn more about the common attributes, please see the related section in the introduction to this chapter. In this recipe, I will go over the specifics for each of these input components. The form component, specified via the h:form tag, is used to create an input form within a JSF view. Each component that is to be processed within the form should be enclosed between the opening and closing h:form tags. Each form typically contains at least one command component, such as a commandButton. A view can contain more than one form component, and only those components that are contained within the form will be processed when the form is submitted. Note■■   I recommend you always specify the id attribute for each component. Most importantly, specify the id attribute for the form component. If you do not specify the id attribute for a given JSF component, then one will be automatically generated for you. The automatic generation of JSF component ids prohibits the ability to statically reference a component from within a scripting language, such as JavaScript, or a managed bean. For instance, in the example for this recipe, the form id attribute is set to contactForm, and the first inputText component id is set to first. This allows you to reference the component statically by appending the form id to the component id from a scripting language or managed bean. In the case of the example, you’d reference the first component as contactForm:first. Each of the input tags support the list of attributes that is shown in Table 5-4, in addition to those already listed as common component attributes in the introduction to this chapter. Figure 5-1.  JSF input form for subscribing to the Acme Bookstore newsletter Chapter 5 ■ JavaServer Faces Standard Components 208 Table 5-4.  Input Component Tag Attributes Attribute Description converter Allows a converter to be applied to the component’s data. converterMessage Specifies a message that will be displayed when a registered converter fails. dir Specifies the direction of text displayed by the component. (LTR is used to indicate left-to-right, and RTL is used to indicate right-to-left.) immediate Flag indicating that, if this component is activated by the user, notifications should be delivered to interested listeners and actions immediately (that is, during the Apply Request Values phase) rather than waiting until the Invoke Application phase. label Specifies a name that can be used for component identification. lang Allows a language code to be specified for the rendered markup. required Accepts a Boolean to indicate whether the user must enter a value for the given component. requiredMessage Specifies an error message to be displayed if the user does not enter a value for a required component. validator Allows a validator to be applied to the component. valueChangeListener Allows a managed bean method to be bound for event-handling purposes. The method will be called when there is a change made to the component. The inputText component is used to generate a single-line text box within a rendered page. The inputText component value attribute is most commonly bound to a managed bean property so that the values of the property can be retrieved or set when a form is processed. In the recipe example, the first inputText component is bound to the managed bean property named first. The EL expression #{contactController1.current.first} is specified for the component value, so if the managed bean’s first property contains a value, then it will be displayed within the inputText component. Likewise, when the form is submitted, then any value that has been entered within the component will be saved within the first property in the managed bean. The inputSecret component is used to generate a single-line text box within a rendered page, and when text is entered into the component, then it is not displayed; rather, asterisks are displayed in place of each character typed. This component makes it possible for a user to enter private text, such as a password, without it being displayed on the screen for others to read. The inputSecret component works identically to the inputText component, other than hiding the text with asterisks. In the example, the value of the inputSecret component is bound to a managed bean property named password via the #{contactController1.current.password} EL expression. The inputTextarea component is used to generate a multiline text box within a rendered page. As such, this component has a couple of additional attributes that can be used to indicate how large the text area should be. The inputTextarea has the rows and cols attributes, which allow a developer to specify how many rows (height) and how many columns (wide) of space the component should take up on the page, respectively. Other than those two attributes, the inputTextarea component works in much the same manner as the inputText component. In the example, the value attribute of the inputTextarea component is specified as #{contactController1.current. description}, so the description property will be populated with the contents of the component when the form is submitted. The input component I have not yet discussed is the inputHidden component. This component is used to place a hidden input field into the form. It works in the same manner as the inputText component, except that it is not rendered on the page for the user to see. The value for an inputHidden component can be bound to a managed bean property in the same way as the other components. You can use such a component for passing a hidden token to and from a form. Chapter 5 ■ JavaServer Faces Standard Components 209 As you can see, the days of passing and receiving request parameters within JSP pages are over. Utilizing the JSF standard input components, it is possible to bind values to managed bean properties using JSF EL expressions. This makes it much easier for developers to submit values from an input form for processing. Rather than retrieving parameters from a page, assigning them to variables, and then processing, the JSF framework takes care of that overhead for you. Although I have not covered the usage of all input component attributes within this recipe, I will cover more in the recipes that follow as I will build upon the Acme Bookstore newsletter subscription page. 5-2. Invoking Actions from Within a Page Problem You want to trigger a server-side method to be invoked from a button or link on one of your application pages. Solution Utilize the commandButton or commandLink components within your view to invoke action methods within a managed bean. The command components allow for the user invocation of actions within managed beans. Command components bind buttons and links on a page directly to action methods, allowing developers to spend more time thinking about the development of the application and less time thinking about the Java servlet–processing life cycle. In the example for this recipe, a button and a link are added to the newsletter page for the Acme Bookstore. The button that will be added to the page will be used to submit the input form for processing, and the link will allow a user to log into the application and manage their subscription and bookstore account. Note■■ this recipe will not cover any authentication features; it focuses only on invoking actions within managed beans. For more information regarding authentication, please see Chapter 14. The View: recipe05_02.xhtml The following code is for the newsletter subscription view including the command components. The sources are for the file named recipe05_02.xhtml.       Chapter 5 ■ JavaServer Faces Standard Components 210

Subscribe to Newsletter

Enter your information below in order to be added to the Acme Bookstore newsletter.












    Managed Bean: ContactController.java The managed bean that contains the action methods is named ContactController, which was created in Recipe 5-1. The following code excerpt is taken from the ContactController class, and it shows the updates that have been made to the methods for this recipe. Note■■ the complete implementation of ContactController resides within the package org.javaeerecipes.chapter05.  Chapter 5 ■ JavaServer Faces Standard Components 211 . . . /** * Adds a subscriber to the newsletter * @return String */ public String subscribe(){ // Using a list implementation for now, // but will add to a database table in Chapter 7   // Add the current contact to the subscription list subscriptionController.getSubscriptionList().add(current); FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Successfully Subscribed to Newsletter for " + getCurrent().getEmail(), null); FacesContext.getCurrentInstance().addMessage(null, facesMsg); return "SUBSCRIBE"; }   /** * Navigational method * @return String */ public String add(){ return "ADD_SUBSCRIBER"; }   /** * This method will allow a user to navigate to the manageAccount view. * This method will be moved into another managed bean that focuses on * authentication later on. * @return */ public String manage(){ return "/chapter05/manageAccount"; } . . .   When the view is rendered, the resulting page looks like Figure 5-2. Chapter 5 ■ JavaServer Faces Standard Components 212 How It Works The command components make JSF vastly different from using JSP technology. In the older technologies, form actions were used to handle request parameters and perform any required business logic with them. With the JSF command components, Java methods can be bound directly to a button or a link and invoked when the components are activated (button or link clicked). In the example for this recipe, both the commandButton and commandLink components are utilized. The commandButton component is used to submit the form request parameters for processing, and the commandLink component is bound to an action method that performs a redirect to another application page. The command components have a handful of attributes that are of note. Those attributes, along with a description of each, are listed in Table 5-5 and Table 5-6. Figure 5-2.  Utilizing command components within a view Table 5-5.  commandButton Component Additional Attributes Attribute Description action EL that specifies a managed bean action method that will be invoked when the user activates the component. actionListener EL that specifies a managed bean action method that will be notified when this component is activated. The action method should be public and accept an ActionEvent parameter, with a return type of void. class CSS style class that can be applied to the component. dir Direction indication for text (LTR: left-to-right; RTL: right-to-left). disabled A Boolean to indicate whether the component is disabled. image Absolute or relative URL to an image that will be displayed on the button. (continued) Chapter 5 ■ JavaServer Faces Standard Components 213 Table 5-6.  commandLink Component Additional Attributes Attribute Description action EL that specifies a managed bean action method that will be invoked when the user activates the component. accessKey Access key value that will transfer the focus to the component. cords Position and shape of the hotspot on the screen. dir Direction indication for text (LTR: left-to-right; RTL: right-to-left). disabled Specifies a Boolean to indicate whether the component is disabled. hreflang Language code of the resource designated by the hyperlink. immediate Flag indicating that, if this component is activated by the user, notifications should be delivered to interested listeners and actions immediately (that is, during the Apply Request Values phase) rather than waiting until the Invoke Application phase. lang Code for the language used for generating the component markup. rel Relationship from the current document to the anchor specified by the hyperlink. rev Reverse anchor specified by this hyperlink to the current document. shape Shape of the hotspot on the screen. tabindex Index value indicating number of tab button presses it takes to bring the component into focus. target Name of a frame where the resource retrieved via the hyperlink will be displayed. title Tooltip that will be displayed when the mouse hovers over component. type Indicates type of button to create. Values are submit (default), reset, and button. charset Character encoding of the resource designated by the hyperlink. Attribute Description immediate Flag indicating that, if this component is activated by the user, notifications should be delivered to interested listeners and actions immediately (that is, during the Apply Request Values phase) rather than waiting until the Invoke Application phase. label Name for the component. lang Code for the language used for generating the component markup. readonly Boolean indicating whether the component is read only. rendererType Identifier of renderer instance. tabindex Index value indicating number of tab button presses it takes to bring the component into focus. title Tooltip that will be displayed when the mouse hovers over component. transient Boolean indicating whether component should be included in the state of the component tree. type Indicates type of button to create. Values are submit (default), reset, and button. Table 5-5.  (continued) Chapter 5 ■ JavaServer FaCeS Standard ComponentS 214 The commandButton and commandLink components in the example to this recipe specify only a minimum number of attributes. That is, they both specify id, action, and value attributes. The id attribute is used to uniquely identify each of the components. The action attribute is set to the JSF EL, which binds the components to their managed bean action methods. The commandButton component has an action attribute of #{contactController2.subscribe}, which means that the ContactController class’s subscribe method will be invoked when the button on the page is clicked. The commandLink has an action attribute of #{contactController2.manage}, which means that the ContactController class’s manage method will be invoked when the link is clicked. Each of the components also specifies a value attribute, which is set to the text that is displayed on the button or link when rendered. As you can see, only a handful of the available attributes are used within the example. However, the components can be customized using the additional attributes that are available. For instance, an actionListener method can be specified, which will bind a managed bean method to the component, and that method will be invoked when the component is activated. JavaScript functions can be specified for each of the attributes beginning with the word on, activating client-side functionality. Command components vastly change the landscape of Java web application development. They allow the incorporation of direct Java method access from within user pages and provide an easy means for processing request parameters. 5-3. Displaying Output Problem You want to display text from a managed bean property within your application pages. Solution Incorporate JSF output components into your views. Output components are used to display static or dynamic text onto a page, as well as the results of expression language arithmetic. The standard JSF component library contains four components that render output: outputLabel, outputText, outputFormat, outputLink, and link. The Acme Bookstore utilizes each of these components within the bookstore newsletter application façade. The View: recipe05_03.xhtml In the following example, the newsletter subscription view has been rewritten to utilize some of the output components: Chapter 5 ■ JavaServer Faces Standard Components 215  

Subscribe to Newsletter













Home
    Managed Bean: ContactController.java The ContactController managed bean has been modified throughout the recipes within this chapter to incorporate new functionality as the recipes move forward. In this recipe, a new property has been added to the ContactController that contains the description of the newsletter. Chapter 5 ■ JavaServer Faces Standard Components 216 Note■■ the hard-coded newsletter description is not a good idea for use in a production application. It is used in this example for demonstration purposes only. For a production application, utilization of resource bundles or database storage would be a more viable approach for storing Strings of text. The following source excerpt from the ContactController class shows the changes:   . . . private String newsletterDescription;   /** * Creates a new instance of ContactController */ public ContactController() { current = null; newsletterDescription = "Enter your information below in order to be " + "added to the Acme Bookstore newsletter."; } . . . /** * @return the newsletterDescription */ public String getNewsletterDescription() { return newsletterDescription; }   /** * @param newsletterDescription the newsletterDescription to set */ public void setNewsletterDescription(String newsletterDescription) { this.newsletterDescription = newsletterDescription; } . . .   The resulting page looks like Figure 5-3. Note that the text is the same, because it is merely reading the same text from a managed bean property. Also note that there is now an additional link added to the bottom of the page, which reads Home. Chapter 5 ■ JavaServer Faces Standard Components 217 How It Works Output components can be used to display output that is generated within a managed bean or to render a link to another resource. They can be useful in many cases for displaying dynamic output to a web view. The example for this recipe demonstrates three out of the five different output component types: outputText, outputLink, and outputLabel. Each of the components shares a common set of attributes, which are listed in Table 5-7. Note■■ the outputText component has become a bit less important since the release of JSF 2.0 because the Facelets view definition language implicitly wraps inline content with a similar output component. Therefore, the use of the outputText tag within JSF 2.0 is necessary only if you want to utilize some of the tag attributes for rendering, JavaScript invocation, or the like. Figure 5-3.  Utilizing output components within a view Table 5-7.  Common Output Component Attributes (Not Listed in Introduction) Attribute Description class CSS class for styling converter Converter that is registered with the component dir Direction of text (LTR: left-to-right; RTL: right-to-left) escape Boolean value to indicate whether XML- and HTML-sensitive characters are escaped lang Code for language used when generating markup for the component parent Parent component title Tooltip text for the component transient Boolean indicating whether component should be included in the state of the component tree Chapter 5 ■ JavaServer Faces Standard Components 218 The outputText component in the example contains a value of #{contactController.newsletterDescription}, which displays the contents of the newsletterDescription property within ContactController. Only the common output component attributes can be specified within the h:outputText tag. Therefore, an attribute such as class or style can be used to apply styles to the text displayed by the component. If the component contains HTML or XML, the escape attribute can be set to true to indicate that the characters should be escaped. The outputFormat component shares the same set of attributes as the outputText component. The outputFormat component can be used to render parameterized text. Therefore, if you require the ability to alter different portions of a String of text, you can do so via the use of JSF parameters (via the f:param tag). For example, suppose you wanted to list the name of books that someone has purchased from the Acme Bookstore; you could use the outputFormat component like in the following example:     The outputLink and outputLabel components can each specify a number of other attributes that are not available to the previously discussed output components. The additional attributes are listed in Table 5-8 (outputLink) and Table 5-9 (outputLabel). The outputLink component can be used to create an anchor or link that will redirect an application user to another page when the link is clicked. In the example, the outputLink component is used to redirect a user to a view named home.xhtml. The value for the outputLink component can be set to a static page name, as per the example, or it can contain a JSF EL expression corresponding to a managed bean property. It is also possible to pass parameters to another page using the outputLink component by nesting f:param tags between opening and closing h:outputLink tags as follows:     Table 5-8.  outputLink Additional Attributes Attribute Description acccessKey Access key value that will transfer the focus to the component. binding ValueExpresssion linking this component to a property in a backing bean. charset The character encoding of the resource designated by this hyperlink. cords Position and shape of the hotspot on the screen. dir Direction indication for text (LTR: left-to-right; RTL: right-to-left). disabled Specifies a Boolean to indicate whether the component is disabled. fragment Identifier for the page fragment that should be brought into focus when the target page is rendered. (continued) Chapter 5 ■ JavaServer Faces Standard Components 219 Table 5-9.  outputLabel Additional Attributes Attribute Description acccessKey Access key value that will transfer the focus to the component. binding ValueExpresssion linking this component to a property in a backing bean. dir Direction indication for text (LTR: left-to-right; RTL: right-to-left). escape Flag indicating that characters that are sensitive in HTML and XML markup must be escaped. for Client identifier of the component for which this element is a label. lang Code for the language used for generating the component markup. tabindex Index value indicating number of Tab button presses it takes to bring the component into focus. title Tooltip that will be displayed when the mouse hovers over component. type Type of button to create. Values are submit (default), reset, and button. The previous example would produce a link with the text User Home Page when rendered on the page. It would produce the following HTML link, where emailAddress corresponds to the EL expression of #{contactController. current.email}:   Home Page   Similarly, rather than displaying a link as text on the page, an image can be used by embedding a graphicImage component (see Recipe 5-6 for details). The outputLabel component renders an HTML