JavaServer Faces

When working with JSP, we saw that it is not a good idea to mix scriptlets with the HTML markup. We solved this problem by using JavaBean. JavaServer Faces takes this design further. In addition to supporting JavaBeans, JSF provides built-in tags for HTML user controls, which are context aware, can perform validation, and can preserve the state between requests. We will now create the login application using JSF:

  1. Create a dynamic web application in Eclipse; let's name it LoginJSFApp. In the last page of the wizard, make sure that you check the Generate web.xml deployment descriptor box.
  2. Download JSF libraries from https://maven.java.net/content/repositories/releases/org/glassfish/javax.faces/2.2.9/javax.faces-2.2.9.jar and copy them to the WEB-INF/lib folder in your project.
  3. JSF follows the MVC pattern. In the MVC pattern, the code to generate user interface (view) is separate from the container of the data (model). The controller acts as the interface between the view and the model. It selects the model for processing a request on the basis of the configuration, and once the model processes the request, it selects the view to be generated and returned to the client, on the basis of the result of the processing in the model. The advantage of MVC is that there is a clear separation of the UI and the business logic (which requires a different set of expertise) so that they can be developed independently, to a large extent. In JSP the implementation of MVC is optional, but JSF enforces the MVC design.

Views are JSF created as xhtml files. The controller is a servlet from the JSF library and models are managed beans (JavaBeans).

We will first configure a controller for JSF. We will add the servlet configuration and mapping in web.xml. Open web.xml from the WEB-INF folder of the project (web.xml should have been created for you by the project wizard if you checked the Generate web.xml deployment descriptor box; step 1). Add the following XML snippet before </web-app>:

<servlet> 
  <servlet-name>JSFServlet</servlet-name> 
  <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> 
  <load-on-startup>1</load-on-startup> 
</servlet> 
 
<servlet-mapping> 
  <servlet-name>JSFServlet</servlet-name> 
  <url-pattern>*.xhtml</url-pattern> 
</servlet-mapping> 

Note that you can get code assist when creating the preceding elements by pressing Ctrl/Cmd + C.

You can specify any name as servlet-name; just make sure that you use the same name in servlet-mapping. The class for the servlet is javax.faces.webapp.FacesServlet, which is in the JAR file that we downloaded as the JSF library and copied to WEB-INF/lib. Furthermore, we have mapped any request ending with .xhtml to this servlet.

Next, we will create a managed bean for our login page. This is the same as JavaBean that we had created earlier, but with the addition of JSF-specific annotations:

  1. Right-click on the src folder under Java Resources for the project in Project Explorer.
  2. Select the New | Class menu option.
  3. Create JavaBean, LoginBean, as described in the Using JavaBeans in JSP section of this chapter.
  4. Create two members for userName and password.
  5. Create the getters and setters for them. Then, add two annotations as follows:
package packt.book.jee_eclipse.bean; 
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.RequestScoped; 
 
@ManagedBean(name="loginBean") 
@RequestScoped 
public class LoginBean { 
  private String userName; 
  private String password; 
  public String getUserName() { 
    return userName; 
  } 
  public void setUserName(String userName) { 
    this.userName = userName; 
  } 
  public String getPassword() { 
    return password; 
  } 
  public void setPassword(String password) { 
    this.password = password; 
  } 
}

(You can get code assist for annotations too. Type @ and press Ctrl/Cmd + C. Code assist works for the annotation key-value attribute pairs too, for example, for the name attribute of the ManagedBean annotation).

  1. Create a new file called index.xhtml inside the WebContent folder of the project by selecting the File | New | File menu option. When using JSF, you need to add a few namespace declarations at the top of the file:
<html xmlns="http://www.w3.org/1999/xhtml" 
  xmlns:f="http://java.sun.com/jsf/core" 
  xmlns:h="http://java.sun.com/jsf/html"> 

Here, we are declaring namespaces for JSF built-in tag libraries. We will access tags in the core JSF tag library with the prefix f and HTML tags with the prefix h.

  1. Add the title and start the body tag:
<head> 
<title>Login</title> 
</head> 
<body> 
  <h2>Login</h2> 

There are corresponding JSF tags for the head and the body, but we do not use any attributes specific to JSF; therefore, we have used simple HTML tags.

  1. We then add the code to display the error message, if it is not null:
<h:outputText value="#{loginBean.errorMsg}" 
              rendered="#{loginBean.errorMsg != null}" 
              style="color:red;"/> 

Here, we use a tag specific to JSF and expression language to display the value of the error message. The OutputText tag is similar to the c:out tag that we saw in JSTL. We have also added a condition to render it only if the error message in the managed bean is not null. Additionally, we have set the color of this output text.

  1. We have not added the errorMsg member to the managed bean yet. Therefore, let's add the declaration, the getter, and the setter. Open the LoginBean class and add the following code:
private String errorMsg; 
public String getErrorMsg() { 
  return errorMsg; 
} 
public void setErrorMsg(String errorMsg) { 
  this.errorMsg = errorMsg; 
} 

Note that we access the managed bean in JSF by using value of the name attribute of the ManagedBean annotation. Furthermore, unlike JavaBean in JSP, we do not create it by using the <jsp:useBean> tag. The JSF runtime creates the bean if it is not already there in the required scope, in this case, the Request scope.

  1. Let's go back to editing index.xhtml. We will now add the following form:
<h:form> 
  User Name: <h:inputText id="userName" 
                value="#{loginBean.userName}"/><br/> 
  Password: <h:inputSecret id="password" 
                value="#{loginBean.password}"/><br/> 
  <h:commandButton value="Submit" 
action="#{loginBean.validate}"/> </h:form>

Many things are happening here. First, we have used the inputText tag of JSF to create textboxes for username and password. We have set their values with the corresponding members of loginBean. We have used the commandButton tag of JSF to create a Submit button. When the user clicks the Submit button, we have set it to call the loginBean.validate method (using the action attribute).

  1. We haven't defined a validate method in loginBean, so let's add that. Open the LoginBean class and add the following code:
public String validate() 
{ 
  if ("admin".equals(userName) && "admin".equals(password)) { 
    errorMsg = null; 
    return "welcome"; 
  } else { 
    errorMsg = "Invalid user id or password. Please try 
again"; return null; } }

Note that the validate method returns a string. How is the return value used? It is used for navigation purposes in JSF. The JSF runtime looks for the JSF file with the same name as the string value returned after evaluating the expression in the action attribute of commandButton. In the validate method, we return welcome if the user credentials are valid. In this case we are telling the JSF runtime to navigate to welcome.xhtml. If the credentials are invalid, we set the error message and return null, in which case, the JSF runtime displays the same page.

  1. We will now add the welcome.xhml page. It simply contains the welcome message:
<html xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:f="http://java.sun.com/jsf/core" 
      xmlns:h="http://java.sun.com/jsf/html"> 
  <body> 
    <h2>Welcome admin !</h2> 
      You are successfully logged in 
  </body> 
</html> 

Here is the complete source code of index.html:

<html xmlns="http://www.w3.org/1999/xhtml" 
  xmlns:f="http://java.sun.com/jsf/core" 
  xmlns:h="http://java.sun.com/jsf/html"> 
 
  <head> 
    <title>Login</title> 
  </head> 
  <body> 
  <h2>Login</h2> 
  <h:outputText value="#{loginBean.errorMsg}" 
  rendered="#{loginBean.errorMsg != null}" 
  style="color:red;"/> 
  <h:form> 
    User Name: <h:inputText id="userName" 
value="#{loginBean.userName}"/><br/> Password: <h:inputSecret id="password"
value="#{loginBean.password}"/><br/> <h:commandButton value="Submit" action="#{loginBean.validate}"/> </h:form> </body> </html>

Here is the source code of the LoginBean class:

package packt.book.jee_eclipse.bean; 
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.RequestScoped; 
 
@ManagedBean(name="loginBean") 
@RequestScoped 
public class LoginBean { 
  private String userName; 
  private String password; 
  private String errorMsg; 
  public String getUserName() { 
    return userName; 
  } 
  public void setUserName(String userName) { 
    this.userName = userName; 
  } 
  public String getPassword() { 
    return password; 
  } 
  public void setPassword(String password) { 
    this.password = password; 
  } 
  public String getErrorMsg() { 
    return errorMsg; 
  } 
  public void setErrorMsg(String errorMsg) { 
    this.errorMsg = errorMsg; 
  } 
  public String validate() 
  { 
    if ("admin".equals(userName) && "admin".equals(password)) { 
      errorMsg = null; 
      return "welcome"; 
    } 
    else { 
      errorMsg = "Invalid user id or password. Please try again"; 
      return null; 
    } 
  } 
} 

To run the application, right-click on index.xhtml in Project Explorer and select the Run As | Run on Server option.

JSF can do much more than what we have seen in this small example—it has the support to validate an input and create page templates too. However, these topics are beyond the scope of this book.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.126.211