Monday, August 24, 2009

Needs Work

Page Navigation and Client Interaction

In this section, we will explore the following concepts:

Page navigation techniques

Taking input from the user

Creating a managed bean

Creating and invoking a do<action> method

These concepts will involve the use of the following JSF centric components, tags and elements:

<h:commandButton>

navigaction-case entries in the faces-config file

managed-bean entries in the faces-config file

So far, we’ve played around a bit with JSF custom tags and internationalization and stuff, but all of that has been largely display generation. If all we wanted to do was display text to the user, we wouldn’t need a Servlet Engine and a JSF framework. No, the really kewl stuff happens when we start taking data from the user, and responding dynamically to the user depending on what type of data and information they deliver to us on the server side.

Two of the biggest challenges associated with building dynamic web applications is first, getting valid information and input from your clients, and secondly, providing an intelligent and informative response to the client based on the information they have provided. So, with these two tasks being the biggest challenges facing a modern day web application developer, nobody should be surprised by the fact that two of the most core features of JSF are the framework’s built-in navigation model, and the framework’s built-in facilities for simplifying the job of obtaining valid user input.

Of course, my challenge is to come up with some slick and friendly application that we could build together to effectively demonstrate the JSF framework’s page navigation and input management capabilities. To keep things fairly fun and light-hearted as we explore some fairly complicated concepts, I thought we’d prototype a little “Rock-Paper-Scissors” type of application.

I know, “Rock-Paper-Scissors” isn’t the most professional and technical of applications that we can develop, but the concept is pretty universal, and using this fun little game will help avoid having to spend too much time trying to explain all of the various use cases and non-JSF related details that might go along with an application that is more technical.

The basic idea of our implementation will be that the client will be asked to pick one of three gestures: Rock, Paper or Scissors. When the client has submitted their choice, the server will choose one of the three possible gestures, Rock Paper or Scissors. And then, the results of the game will be evaluated, and a response summarizing the results of the game will be sent back to the client. It’s all a pretty simple concept.

*Note, the term ‘gesture’ is used to describe the three choices of Rock, Paper and Scissors. The reason the term ‘gesture’ is used is because when the game is played interactively between two people, hand gestures are used to represent the choice of rock, paper or scissors.

clip_image002

Our online version of the Rock Paper Scissors game will involve five web pages, with the first page prompting the end user to type either Rock, Paper or Scissors into a textfield, after which, they will need to click on a submit button to initiate game play.

The game has three possible outcomes, either a win, lose, or tie. And actually, I’m going to include a fourth outcome, which is failure, which could happen if something either goes wrong, or perhaps the client hasn’t provided a valid option for game play. So, to accommodate our four possible outcomes, we will need to create an additional four JSP pages, named win.jsp, lose.jsp, tie.jsp and failure.jsp.

***Images go here.

Overall Application Flow

So, we have established that our little application needs five simple JSP pages: one for input, three to represent a potential result of win, lose or tie, and finally, a failure page to handle any errors or problems. But the question is: how do we get from the input page to the results page? I mean, there is a little bit of logic involved in order to decide whether there has been a win or a loss, and of course, we want to see the JSF framework’s neat page navigation features in action, right? Well, here’s how it is all going to work:

The first page the user will touch will have a textfield and a submit button on it. When the user types in a gesture and clicks the submit button, a request will go across the network and subsequently be captured by our application’s JSF framework. Of course, our application is going to need to first figure out what the user chose as their gesture, chose a gesture of its own, and then perform the multi-variable calculus required to figure out if the client won, lost, or tied. Of course, this is application logic, and we will need to code this application logic into a JavaBean. So, we’re going to need to create a JavaBean called the RPSBean (RPS=Rock, Paper, Scissors), and in that bean we will code a method named doRockPaperScissorsGame(). It is inside this method that we will code the required application logic.

The JSF framework will create an instance of the RPSBean for us, it will invoke the doRockPaperScissorsGame() method at the appropriate time for us, and it will take responsibility for figuring out when the Java Virtual Machine’s garbage collector will be able to get it’s greasy little fingers on the JSF created instance of the RPSBean and dispose of it. So, although we’re going to have to code a thing or two into this RPSBean class, the lifecycle of this JavaBean will be managed by the JSF framework. Given this fact, it’s not surprising that in JSF parlance, we call this type of JavaBean a ‘managed bean.’ All JSF managed beans must be described in the faces-config.xml file.

And speaking of the faces-config.xml file, there are a few other salacious entries that we are going to have to make in there if we want our application to work properly. You see, when our doRockPaperScissors() method executes, it must return a String. The String, which for us will simply be the words ‘win’, ‘lose’, ‘tie’ or ‘failure’, map to a navigation-rule from-outcome entry in the faces-config.xml file. The JSF framework then uses the returned String from the doRockPaperScissorsGame() method to figure out which JSP page will be invoked in order to produce a response. When the JSP is invoked, the appropriate markup gets created, and the response is then sent back to the user.

So, in summary, when the client clicks submit, a request is captured by the JSF framework. The JSF framework will look at the request, and not only create in instance of the appropriate JavaBean, but it will also invoke the method needed to implement the required application logic. When the logic is complete, the method will spit out a text String, and based on a corresponding text entry in the faces-config.xml file, the framework will figure out which JSP page will be called upon for generating a response that will get sent back to the client. And that’s it!

***Diagram showing the flow

The Landing Page

The landing page which is first viewed by the client is tasked with providing a textfield and a submit button, along with a bit of directions, to the end user.

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

    Please chose between Rock Paper and Scissors:
    <h:form id="rpsgame" >
        <h:inputText id="gesture" value=”#{rpsbean.clientGesture}”> </h:inputText>
        <h:commandButton id="submit" type="submit" value="Play!" action="#{rpsbean.doRockPaperScissorsGame}" ></h:commandButton>
    </h:form>
    </body>

</f:view>
</html>

There isn’t too much magic on this page. The required taglib directives decorate the top of the page, we have the standard form tag which then wraps both the h:inputText and the h:commandButton tags.

    <h:form id="rpsgame" >
        <h:inputText id="gesture" value= ”#{rpsbean.clientGesture}” > </h:inputText>
        <h:commandButton type="submit" value="Play!"

action="#{rpsbean.doRockPaperScissorsGame}" ></h:commandButton>

    </h:form>

The first thing to notice here is the value attribute of the inputText tag. We need to be able to take whatever the client types into the textfield and have that transferred to the server, where we can process it. The ”#{rpsbean.clientGesture}” entry for the value attribute tells the JSF framework that whatever is typed into this textfield should be transferred to a property named clientGesture in a JavaBean that is running on the server that is named rpsbean.

The second thing that needs to be pointed out here is the action attribute of the h:commandButton tag. Notice how the action attribute is set to "#{rpsbean.doRockPaperScissorsGame}"

The hash code sign, #, is a signal that tells the JSF framework that some JSF-specific processing is required. In this case, the JSF framework recognizes the fact that any time a submit button is clicked, processing logic is required, and in this case, the JSF framework will invoke the doRockPaperScissorsGame method of the rpsbean.

Another thing worth pointing out here are the id attributes that have been assigned to the form and inputText elements. JSF links elements and sub-elements according to their names or ids, in a ancestor:parent:child type of syntax. So, when we do processing and try to figure out what a user typed into the textbox, we can identify the inputText field with the id of gesture, inside the form named rpsgame, with the name rpsgame:gesture.

The syntax used here to specify the value of the action attribute is known as JSF expression language, and while the result of using this syntax will be to have the JSF framework invoke a method on a JavaBean, it is worth nothing that the syntax we see here is not a Java syntax. JSF expression langugage is intended to look and feel more like a scripting language, helping to keep JSP pages look cleaner, be free from actual Java code, and subsequently making JSPs easier to write and maintain.

So, our h:inputText tag is looking for a JavaBean named rpsbean so, it would probably be prudent to create such a JavaBean that will fill this need.

The basic outline of the JavaBean will look like this:

package com.mcnz.jsf.bean;

import javax.faces.context.*;

public class RPSBean {
    }
}

I’ve placed the bean in a package named com.mcnz.jsf.bean, I have been generous to myself and imported javafaces.context.*, and I have created a simple class named RPSBean. When you create your own class, make sure the RPSB is all capitalized – case is important!

Now, after coding the class declaration, the next thing you’ll want to think about are any instance variables the class might need. Our little RPSBean will probably need to keep track of the client gesture, and the computer’s gesture, so making two String variables, one named computerGesture and the other named clientGesture, probably wouldn’t be such a bad idea.

Now, one thing to note about methods called from the action attribute of a custom tag is the fact that those methods must return a text String.

The text String is supposed to provide the JSF framework some type of guidance as to how to mitigate page navigation, so in our case, we will have four possibilities, the Strings: “failure”, “win”, “lose” and “tie”.

It’s always a good habit to start off your do<action> method by explicitly setting a String named result to a valid value, which in this case we set to failure, and then specifying what will be the last line of code in the method, return result;

package com.mcnz.jsf.bean;

import javax.faces.context.FacesContext;

public class RPSBean {
    public String doRockPaperScissorsGame() {
        String result = "failure";
/*Method implementation logic will go here. */
        return result;
    }

}

Of course, we need to keep track of what the client selected, and what the computer has selected, so we’ll add two instance variables of type String to our RPSBean. We will add the setters and getters as well.

1 comment:

  1. Work is work. It is needed in all the stage of life. Please specify what kind of work you wanna need.

    kollagen

    ReplyDelete

Followers