Este contenido no está disponible en el idioma seleccionado.
1.5. Seam pageflow: the numberguess example
For Seam applications with freeform (ad hoc) navigation, JSF/Seam navigation rules are a good way to define page flow. However, in applications with more constrained navigation styles, especially user interfaces that are more stateful, navigation rules make understanding system flow difficult. Combining information from view pages, actions, and navigation rules makes this flow easier to understand.
With Seam, jPDL process definition can be used to define pageflow, as seen in the number guessing example that follows.
Copy to ClipboardCopied!Toggle word wrapToggle overflow
The <page> element defines a wait state where the system displays a particular JSF view and waits for user input. The view-id is the same JSF view id used in plain JSF navigation rules. The redirect attribute tells Seam to use post-then-redirect when navigating to the page. (This results in friendly browser URLs.)
The <transition> element names a JSF outcome. The transition is triggered when a JSF action results in that outcome. Execution will then proceed to the next node of the pageflow graph, after invocation of any jBPM transition actions.
A transition <action> is just like a JSF action, except that it occurs when a jBPM transition occurs. The transition action can invoke any Seam component.
A <decision> node branches the pageflow, and determines the next node to execute by evaluating a JSF EL expression.
In the JBoss Developer Studio pageflow editor, the pageflow looks like this:
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Note that the command button names the guess transition instead of calling an action directly.
The win.jspx page is predictable:
Example 1.25. win.jspx
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns="http://www.w3.org/1999/xhtml"
version="2.0">
<jsp:output doctype-root-element="html"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
doctype-system="http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<jsp:directive.page contentType="text/html"/>
<html>
<head>
<title>You won!</title>
<link href="niceforms.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>You won!</h1>
<f:view>
Yes, the answer was
<h:outputText value="#{numberGuess.currentGuess}" />.
It took you
<h:outputText value="#{numberGuess.guessCount}" /> guesses.
<h:outputText value="But you cheated, so it doesn't count!"
rendered="#{numberGuess.cheat}"/>
Would you like to <a href="numberGuess.seam">play again</a>?
</f:view>
</body>
</html>
</jsp:root>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns="http://www.w3.org/1999/xhtml"
version="2.0">
<jsp:output doctype-root-element="html"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
doctype-system="http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<jsp:directive.page contentType="text/html"/>
<html>
<head>
<title>You won!</title>
<link href="niceforms.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>You won!</h1>
<f:view>
Yes, the answer was
<h:outputText value="#{numberGuess.currentGuess}" />.
It took you
<h:outputText value="#{numberGuess.guessCount}" /> guesses.
<h:outputText value="But you cheated, so it doesn't count!"
rendered="#{numberGuess.cheat}"/>
Would you like to <a href="numberGuess.seam">play again</a>?
</f:view>
</body>
</html>
</jsp:root>
Copy to ClipboardCopied!Toggle word wrapToggle overflow
The lose.jspx is very similar, so we have not included it here.
Finally, the application code is as follows:
Example 1.26. NumberGuess.java
@Name("numberGuess")
@Scope(ScopeType.CONVERSATION)
public class NumberGuess implements Serializable {
private int randomNumber;
private Integer currentGuess;
private int biggest;
private int smallest;
private int guessCount;
private int maxGuesses;
private boolean cheated;
@Create
public void begin()
{
randomNumber = new Random().nextInt(100);
guessCount = 0;
biggest = 100;
smallest = 1;
}
public void setCurrentGuess(Integer guess)
{
this.currentGuess = guess;
}
public Integer getCurrentGuess()
{
return currentGuess;
}
public void guess()
{
if (currentGuess>randomNumber)
{
biggest = currentGuess - 1;
}
if (currentGuess<randomNumber)
{
smallest = currentGuess + 1;
}
guessCount ++;
}
public boolean isCorrectGuess()
{
return currentGuess==randomNumber;
}
public int getBiggest()
{
return biggest;
}
public int getSmallest()
{
return smallest;
}
public int getGuessCount()
{
return guessCount;
}
public boolean isLastGuess()
{
return guessCount==maxGuesses;
}
public int getRemainingGuesses() {
return maxGuesses-guessCount;
}
public void setMaxGuesses(int maxGuesses) {
this.maxGuesses = maxGuesses;
}
public int getMaxGuesses() {
return maxGuesses;
}
public int getRandomNumber() {
return randomNumber;
}
public void cheated()
{
cheated = true;
}
public boolean isCheat() {
return cheated;
}
public List<Integer> getPossibilities()
{
List<Integer> result = new ArrayList<Integer>();
for(int i=smallest; i<=biggest; i++) result.add(i);
return result;
}
}
@Name("numberGuess")
@Scope(ScopeType.CONVERSATION)
public class NumberGuess implements Serializable {
private int randomNumber;
private Integer currentGuess;
private int biggest;
private int smallest;
private int guessCount;
private int maxGuesses;
private boolean cheated;
@Create
public void begin()
{
randomNumber = new Random().nextInt(100);
guessCount = 0;
biggest = 100;
smallest = 1;
}
public void setCurrentGuess(Integer guess)
{
this.currentGuess = guess;
}
public Integer getCurrentGuess()
{
return currentGuess;
}
public void guess()
{
if (currentGuess>randomNumber)
{
biggest = currentGuess - 1;
}
if (currentGuess<randomNumber)
{
smallest = currentGuess + 1;
}
guessCount ++;
}
public boolean isCorrectGuess()
{
return currentGuess==randomNumber;
}
public int getBiggest()
{
return biggest;
}
public int getSmallest()
{
return smallest;
}
public int getGuessCount()
{
return guessCount;
}
public boolean isLastGuess()
{
return guessCount==maxGuesses;
}
public int getRemainingGuesses() {
return maxGuesses-guessCount;
}
public void setMaxGuesses(int maxGuesses) {
this.maxGuesses = maxGuesses;
}
public int getMaxGuesses() {
return maxGuesses;
}
public int getRandomNumber() {
return randomNumber;
}
public void cheated()
{
cheated = true;
}
public boolean isCheat() {
return cheated;
}
public List<Integer> getPossibilities()
{
List<Integer> result = new ArrayList<Integer>();
for(int i=smallest; i<=biggest; i++) result.add(i);
return result;
}
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
The first time a JSP page asks for a numberGuess component, Seam will create a new one for it, and the @Create method will be invoked, allowing the component to initialize itself.
The pages.xml file starts a Seam conversation, and specifies the pageflow definition to use for the conversation's page flow. Refer to Chapter 8, Conversations and workspace management for more information.
Ayudamos a los usuarios de Red Hat a innovar y alcanzar sus objetivos con nuestros productos y servicios con contenido en el que pueden confiar. Explore nuestras recientes actualizaciones.
Hacer que el código abierto sea más inclusivo
Red Hat se compromete a reemplazar el lenguaje problemático en nuestro código, documentación y propiedades web. Para más detalles, consulte el Blog de Red Hat.
Acerca de Red Hat
Ofrecemos soluciones reforzadas que facilitan a las empresas trabajar en plataformas y entornos, desde el centro de datos central hasta el perímetro de la red.