SeamFramework.orgCommunity Documentation
The Web Beans is being developed at the Seam project. You can download the latest developer release of Web Beans from the the downloads page.
Web Beans comes with a two deployable example applications: webbeans-numberguess
, a war example, containing only simple beans, and webbeans-translator
an ear example, containing enterprise beans. There are also two variations on the numberguess example, the tomcat example (suitable for deployment to Tomcat) and the jsf2 example, which you can use if you are running JSF2. To run the examples you'll need the following:
the latest release of Web Beans,
JBoss AS 5.0.1.GA, or
Apache Tomcat 6.0.x, and
Ant 1.7.0.
You'll need to download JBoss AS 5.0.1.GA from jboss.org, and unzip it. For example:
$ cd /Applications $ unzip ~/jboss-5.0.1.GA.zip
Next, download Web Beans from seamframework.org, and unzip it. For example
$ cd ~/ $ unzip ~/webbeans-$VERSION.zip
Después necesitaremos decirle a Web Beans en dónde está localizado JBoss. Editar jboss-as/build.properties
y establecer la propiedad jboss.home
. Por ejemplo:
jboss.home=/Applications/jboss-5.0.1.GA
To install Web Beans, you'll need Ant 1.7.0 installed, and the ANT_HOME
environment variable set. For example:
$ unzip apache-ant-1.7.0.zip $ export ANT_HOME=~/apache-ant-1.7.0
Then, you can install the update. The update script will use Maven to download Web Beans automatically.
$ cd webbeans-$VERSION/jboss-as $ ant update
Ahora, ¡está listo para desplegar su primer ejemplo!
The build scripts for the examples offer a number of targets for JBoss AS, these are:
ant restart
- despliega el ejemplo en formato explotado
ant explode
- actualiza un ejemplo explotado, sin reiniciar el despliegue
ant deploy
- despliega el ejemplo en formato JAR comprimido
ant undeploy
- quita el ejemplo del servidor
ant clean
- borra el ejemplo
Para desplegar el ejemplo numberguess:
$ cd examples/numberguess ant deploy
Start JBoss AS:
$ /Application/jboss-5.0.0.GA/bin/run.sh
If you use Windows, use the run.bat
script.
Espere que despliegue la aplicación, y diviértase en http://localhost:8080/webbeans-numberguess!
Web Beans includes a second simple example that will translate your text into Latin. The numberguess example is a war example, and uses only simple beans; the translator example is an ear example, and includes enterprise beans, packaged in an EJB module. To try it out:
$ cd examples/translator ant deploy
Espere a que despliegue la aplicación, y ¡visite http://localhost:8080/webbeans-translator!
You'll need to download Tomcat 6.0.18 or later from tomcat.apache.org, and unzip it. For example:
$ cd /Applications $ unzip ~/apache-tomcat-6.0.18.zip
Next, download Web Beans from seamframework.org, and unzip it. For example
$ cd ~/ $ unzip ~/webbeans-$VERSION.zip
Next, we need to tell Web Beans where Tomcat is located. Edit jboss-as/build.properties
and set the tomcat.home
property. For example:
tomcat.home=/Applications/apache-tomcat-6.0.18
The build scripts for the examples offer a number of targets for Tomcat, these are:
ant tomcat.restart
- deploy the example in exploded format
ant tomcat.explode
- update an exploded example, without restarting the deployment
ant tomcat.deploy
- deploy the example in compressed jar format
ant tomcat.undeploy
- remove the example from the server
ant tomcat.clean
- clean the example
To deploy the numberguess example for tomcat:
$ cd examples/tomcat ant tomcat.deploy
Start Tomcat:
$ /Applications/apache-tomcat-6.0.18/bin/startup.sh
If you use Windows, use the startup.bat
script.
Espere que despliegue la aplicación, y diviértase en http://localhost:8080/webbeans-numberguess!
En la aplicación numberguess se le dan 10 intentos para adivinar un número entre 1 y 100. Después de cada intento, se le dirá si es mayor o menor a su número.
El ejemplo de numberguess consta de una cantidad de Web Beans, archivos de configuración y páginas Facelet JSF, empaquetadas como WAR. Empecemos con los archivos de configuración.
Todos los archivos de configuración para este ejemplo están localizados en WEB-INF/
, el cual está almacenado en WebContent
en el árbol fuente. Primero, tenemos faces-config.xml
, en donde le pedimos a JSF que utilice Facelets:
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="1.2"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
<application>
<view-handler
>com.sun.facelets.FaceletViewHandler</view-handler>
</application>
</faces-config
>
Hay un archivo web-beans.xml
vacío, el cual marca esta aplicación como una aplicación de Web Beans.
Por último, está web.xml
:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name >Web Beans Numbergues example</display-name> <!-- JSF --><servlet> <servlet-name >Faces Servlet</servlet-name> <servlet-class >javax.faces.webapp.FacesServlet</servlet-class> <load-on
-startup >1</load-on-startup> </servlet> <servlet-mapping> <servlet
-name >Faces Servlet</servlet-name> <url-pattern >*.jsf</url-pattern> </servlet-mapping>
<context-param> <param-name >javax.faces.DEFAULT_SUFFIX</param-name> <param-v
alue >.xhtml</param-value> </context-param> <session-config> <session-timeout >10</session-timeout> </session-config> </web-app >
![]() | Enable and load the JSF servlet |
![]() | Configure requests to |
![]() | Tell JSF that we will be giving our source files (facelets) an extension of |
![]() | Configure a session timeout of 10 minutes |
Whilst this demo is a JSF demo, you can use Web Beans with any Servlet based web framework.
Let's take a look at the Facelet view:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:s="http://jboss.com/products/seam/taglib"> <ui:composition template="template.xhtml"> <ui:define name="content"> <h1 >Guess a number...</h1> <h:form
id="NumberGuessMain"> <div style="color: red"> <h:messages id="messages" globalOnly="false"/> <h:outputText id="Higher" value="Higher!" rendered="#{game.number gt game.guess and game.guess ne 0}"/> <h:outputText id="Lower" value="Lower!" rendered="#{game.number lt game.guess and game.guess ne 0}"/> </div> <div
> I'm thinking of a number between #{game.smallest} and #{game.biggest}. You have #{game.remainingGuesses} guesses. </div> <div> Y
our guess: <h:inputText id="inputGuess" value="#{game.guess}" required="true" size="3"
disabled="#{game.number eq game.guess}"> <f:validateLongRange maximum="#{game.biggest}" minimum="#{game.smallest}"/> <
/h:inputText> <h:commandButton id="GuessButton" value="Guess" action="#{game.check}" disabled="#{game.number eq game.guess}"/> </div> <div> <h:commandButton id="RestartButton" value="Reset" action="#{game.reset}" immediate="true" /> </div> </h:form> </ui:define> </ui:composition> </html >
![]() | Facelets is a templating language for JSF, here we are wrapping our page in a template which defines the header. |
![]() | There are a number of messages which can be sent to the user, "Higher!", "Lower!" and "Correct!" |
![]() | As the user guesses, the range of numbers they can guess gets smaller - this sentance changes to make sure they know what range to guess in. |
![]() | This input field is bound to a Web Bean, using the value expression. |
![]() | A range validator is used to make sure the user doesn't accidentally input a number outside of the range in which they can guess - if the validator wasn't here, the user might use up a guess on an out of range number. |
![]() | And, of course, there must be a way for the user to send their guess to the server. Here we bind to an action method on the Web Bean. |
El ejemplo existe de 4 clases, las primeras dos son tipos de enlace. Primero, hay un tipo de enlace @Random
, utilizado para inyectar un número aleatorio:
@Target( { TYPE, METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
@Documented
@BindingType
public @interface Random {}
También hay un tipo de enlace @MaxNumber
, utilizado para inyectar el número máximo posible:
@Target( { TYPE, METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
@Documented
@BindingType
public @interface MaxNumber {}
La clase Generator
es responsable de crear el número aleatorio, a través de un método de productor. También expone el número máximo posible a través del método de productor:
@ApplicationScoped
public class Generator {
private java.util.Random random = new java.util.Random( System.currentTimeMillis() );
private int maxNumber = 100;
java.util.Random getRandom()
{
return random;
}
@Produces @Random int next() {
return getRandom().nextInt(maxNumber);
}
@Produces @MaxNumber int getMaxNumber()
{
return maxNumber;
}
}
Notará que el Generador
es una aplicación en ámbito por lo tanto no obtenemos un número aleatorio diferente cada vez.
El Web Bean final en la aplicación es la sesión en ámbito Juego
.
Notará que hemos utilizado la anotación @Named
, para poder utilizar el bean a través de EL en la página JSF. Por último, hemos utilizado la inyección de constructor para inicializar el juego con un número aleatorio. Y, claro está, necesitamos decirle al jugador cuando haya ganado, por lo tanto le damos retroalimentación con FacesMessage
.
package org.jboss.webbeans.examples.numberguess;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.webbeans.AnnotationLiteral;
import javax.webbeans.Current;
import javax.webbeans.Initializer;
import javax.webbeans.Named;
import javax.webbeans.SessionScoped;
import javax.webbeans.manager.Manager;
@Named
@SessionScoped
public class Game
{
private int number;
private int guess;
private int smallest;
private int biggest;
private int remainingGuesses;
@Current Manager manager;
public Game()
{
}
@Initializer
Game(@MaxNumber int maxNumber)
{
this.biggest = maxNumber;
}
public int getNumber()
{
return number;
}
public int getGuess()
{
return guess;
}
public void setGuess(int guess)
{
this.guess = guess;
}
public int getSmallest()
{
return smallest;
}
public int getBiggest()
{
return biggest;
}
public int getRemainingGuesses()
{
return remainingGuesses;
}
public String check()
{
if (guess
>number)
{
biggest = guess - 1;
}
if (guess<number)
{
smallest = guess + 1;
}
if (guess == number)
{
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Correct!"));
}
remainingGuesses--;
return null;
}
@PostConstruct
public void reset()
{
this.smallest = 0;
this.guess = 0;
this.remainingGuesses = 10;
this.number = manager.getInstanceByType(Integer.class, new AnnotationLiteral<Random
>(){});
}
}
The numberguess for Tomcat differs in a couple of ways. Firstly, Web Beans should be deployed as a Web Application library in WEB-INF/lib
. For your convenience we provide a single jar suitable for running Web Beans on Tomcat webbeans-tomcat.jar
.
Of course, you must also include JSF and EL, as well common annotations (jsr250-api.jar
) which a JEE server includes by default.
Secondly, we need to explicitly specify the Tomcat servlet listener (used to boot Web Beans, and control it's interaction with requests) in web.xml
:
<listener> <listener-class>org.jboss.webbeans.environment.tomcat.Listener</listener-class> </listener>
El ejemplo de traductor tomará las oraciones que entre y las traducirá en Latín.
El ejemplo de traductor está incorporado como un EAR, y contiene EJB. Como resultado, su estructura es más compleja que el ejemplo de Numberguess.
EJB 3.1 y Java EE 6 le permiten empaquetar EJB en un WAR, lo cual hará la estructura mucho más simple!
Primero, demos una mirada al agregador EAR, el cual está localizado en el módulo webbeans-translator-ear
. Maven genera automáticamente la application.xml
:
<plugin>
<groupId
>org.apache.maven.plugins</groupId>
<artifactId
>maven-ear-plugin</artifactId>
<configuration>
<modules>
<webModule>
<groupId
>org.jboss.webbeans.examples.translator</groupId>
<artifactId
>webbeans-translator-war</artifactId>
<contextRoot
>/webbeans-translator</contextRoot>
</webModule>
</modules>
</configuration>
</plugin
>
Aquí establecemos la ruta de contexto, la cual nos da una url interesante (http://localhost:8080/webbeans-translator).
Si no está utilizando Maven para generar estos archivos, usted necesitaría META-INF/application.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd"
version="5">
<display-name
>webbeans-translator-ear</display-name>
<description
>Ejemplo Ear para la implementaci�n de referencia de JSR 299: Web Beans</description>
<module>
<web>
<web-uri
>webbeans-translator.war</web-uri>
<context-root
>/webbeans-translator</context-root>
</web>
</module>
<module>
<ejb
>webbeans-translator.jar</ejb>
</module>
</application
>
Next, lets look at the war. Just as in the numberguess example, we have a faces-config.xml
(to enable Facelets) and a web.xml
(to enable JSF) in WebContent/WEB-INF
.
Más interesante aún es el facelet utilizado para traducir texto. Al igual que en el ejemplo de Numberguess tenemos una plantilla, la cual rodea el formulario (omitido aquí por razones de brevedad):
<h:form id="NumberGuessMain">
<table>
<tr align="center" style="font-weight: bold" >
<td>
Your text
</td>
<td>
Translation
</td>
</tr>
<tr>
<td>
<h:inputTextarea id="text" value="#{translator.text}" required="true" rows="5" cols="80" />
</td>
<td>
<h:outputText value="#{translator.translatedText}" />
</td>
</tr>
</table>
<div>
<h:commandButton id="button" value="Translate" action="#{translator.translate}"/>
</div>
</h:form
>
El usuario puede entrar texto en el área de texto a mano izquierda y pulsar el botón de traducir para ver el resultado a la derecha.
Por último, veamos el módulo EJB, webbeans-translator-ejb
. En src/main/resources/META-INF
sólo hay un web-beans.xml
vacío, utilizado para marcar el archivo como si contuviera Web Beans.
Hemos guardado la parte más interesante para el final, ¡el código! El proyecto tiene dos beans sencillos, SentenceParser
y TextTranslator
y dos beans empresariales, TranslatorControllerBean
y SentenceTranslator
. Por ahora, debe comenzar a familiarizarse con el aspecto de Web Bean, por lo tanto sólo destacaremos aquí las partes más interesantes.
Tanto SentenceParser
como TextTranslator
son beans dependientes, y TextTranslator
utiliza inicialización de constructor:
public class TextTranslator {
private SentenceParser sentenceParser;
private Translator sentenceTranslator;
@Initializer
TextTranslator(SentenceParser sentenceParser, Translator sentenceTranslator)
{
this.sentenceParser = sentenceParser;
this.sentenceTranslator = sentenceTranslator;
TextTranslator
es un bean con estado (con una interfaz local de negocios), donde lo mágico sucede - claro está, que no desarrollaramos un traductor completo, ¡pero le dimos una buena luz!
Por último, hay un controlador orientado a UI que recoge el texto desde el usuario y lo envía al traductor. Esta es una petición en ámbito, llamada bean con estado de sesión que inyecta el traductor.
@Stateful
@RequestScoped
@Named("translator")
public class TranslatorControllerBean implements TranslatorController
{
@Current TextTranslator translator;
El bean también tiene capturadores y configuradores para todos los campos en la página.
Como este es un bean de sesión con estado, tenemos que tener un método de eliminación:
@Remove
public void remove()
{
}
El administrador de Web Beans llamará al método de eliminación cuando el bean sea destruido, en este caso al final de la petición.
That concludes our short tour of the Web Beans examples. For more on Web Beans , or to help out, please visit http://www.seamframework.org/WebBeans/Development.
Necesitamos ayuda en todas las áreas - corrección de errores, escritura de nuevas funciones, escritura de ejemplos y traducción de esta guía de referencia.