div

Anuncio
JSF
María Consuelo Franky
Universidad Javeriana
2009
1
JSF: Java Server Faces
la nueva generación de páginas web en
tecnología Java
2
Niveles de una arquitectura multi-nivel
Presentación
•Maneja
interacción
con usuario
•Despliegue
HTML
•Validación
Aplicación
Servicios
•Invoca
•Realiza
servicios
•Validación
sintáctica
•Adapta
respuestas
a interfaz
usuario
sintáctica
•Maneja
excepciones
Cliente con
navegador Web
servicios
sobre
objetos del
dominio
•Implanta
reglas del
negocio
•Estado de
sesión
-usuario
Dominio
Persistencia
•Servicios
•Modela
entidades
del negocio
y sus reglas
básicas
•Validación
semántica
•Control
básicos de
persistencia
de objetos
del dominio
•Transformación ObjetoRelacional
•Soporte
transacción
transacción
Servidor Web
Servidor de Componentes
Servidor BD
3
El metapatrón MVC
• Model (Modelo): maneja reglas del negocio y estructura de los datos
• View (Vistas): maneja presentación de los datos del sistema al usuario
• Controller (Controlador): transforma pedidos del usuario en operaciones
sobre los objetos del modelo y selecciona vista para mostrar resultados al
usuario (comportamiento del sistema)
4
Nivel web basado en el framework JSF
Pantallas se contruyen con componentes gráficos UIComponent
que reaccionan a eventos:
son componentes de alto nivel que encapsulan elementos HTML y
tienen comportamiento asociado
muestran y actualizan valores del Modelo contenidos en javaBeans
asociados ("backing beans")
como reacción a eventos (por ej: oprimir un botón) invocan
directamente métodos de los “backing beans”
Aspectos de validación de los datos del usuario:
Validación automática asociada a cada componente gráfico
Cuando la validación falla se vuelve a mostrar la pantalla junto con
los mensajes de error
Procesamiento de eventos solo cuando la validación es exitosa
5
Framework JSF
Presentación
Aplicación
Servicios
Dominio
Persistencia
CONTROLADOR
MODELO
servlet Faces
EJB
entidad
C
Backing
Bean 1
Backing
Bean 2
HTML
1
HTML
2
Navegador
Cliente
EJB
sesión
A
BD
relacional
JSP
pantallazo1
JSP
pantallazo2
VISTAS
Servidor Web
Servidor de
componentes
Servidor BD6
Ejemplo de pantalla JSF:
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<html>
<head>
<title>Add 2 numbers</title>
</head>
<body>
<f:view>
<h:form id="addForm">
First Number:
<h:inputText id="firstNumber"
value="#{BackCalc.firstNumber}" required="true" />
<h:message for="firstNumber" /> <br>
Second Number:
<h:inputText id="secondNumber"
value="#{BackCalc.secondNumber}" required="true" />
<h:message for="secondNumber" /> <br>
Result:
<h:outputText id="output" value="#{BackCalc.result}" /> <br>
<h:commandButton id="submitAdd"
action="#{BackCalc.add}" value="Add" />
</h:form>
</f:view>
</body>
7
</html>
backing bean para el pantallazo:
public class BackCalc {
// atributos ligados a los UIComponents:
private int firstNumber = 0;
private int secondNumber = 0;
private int result = 0;
// model: podria ser la referencia a un EJB:
private Calculator calculator = new Calculator();
//. . . metodos set y get de atributos . . .
// reaccion a evento sobre el boton:
public String add() {
result = calculator.add(firstNumber, secondNumber);
return "success";
}
}
8
Validación automática:
abc
"firstNumber": Conversion error occured
Validation Error: "secondNumber":
Value is required
9
Pantalla JSF simple
10
Pantalla de edición
11
Expone los atributos de un backing bean
...
<div class="label">Name:</div>
<div class="input">
<h:inputText id="name" value="#{hotel.name}"
required="true" />
<br/>
<span class="errors"><h:message for="name" /></span>
</div>
Hay una zona para los mensajes FacesMessages
<div class="entry errors">
<h:messages globalOnly="true" />
</div>
Los botones invocan acciones sobre un backing bean
<div class="input">
<h:commandButton id="proceed" value="Proceed"
action="#{hotel.verifyNewHotel}"
styleClass="button"/> 
<s:button value="Cancel" id="cancel"
action="#{hotel.cancel}"
styleClass="button"/>
</div>
12
Pantalla no editable
13
Pantalla para ver datos de hotel sin editar: confirmHotel
muestra cada atributo de un hotel, por ej name :
<div class="entry">
<div class="label">Name:</div>
<div class="output">
<h:outputText id="name" value="#{hotel.name}" />
</div>
</div>
botones finales para invocar confirm(), cancel() o regresar a la pantalla anterior
<div class="input">
<h:commandButton id="confirm" value="Confirm"
action="#{hotel.confirm}"
styleClass="button"/>  
<h:commandButton id="revise" value="Revise"
action="backEditHotel"
styleClass="button"/> 
<h:commandButton id="cancel" value="Cancel"
action="#{hotel.cancel}"
styleClass="button"/>
</div>
observar el alias "backEditHotel" definido como alias en faces-config.xml
referente a /pages/hotels/hotelInscription/editHotel.xhtml
14
Estructuración de pantallas “facelets”
mediante templates y <div>
15
Concepto de template
Concepto de template (plantilla):
pantalla base que define estructura común de las pantallas reales
contiene partes fijas y partes que deben ser redefinidas por cada pantalla
ejemplo de estructura de pantalla:
banner
sidebar
content
footer
16
Ejemplo de plantilla: template.xhtml
<!-- librerias de etiquetas -->
<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"
xmlns:rich="http://richfaces.ajax4jsf.org/rich">
<!-- referencia al archivo que define estilos de los div -->
<head>
<meta http-equiv="Content-Type"
content="text/html;charset=iso-8859-1" />
<title>Hotels reservation system</title>
<link
href="#{facesContext.externalContext.requestContextPath}
/pages/public/css/screen.css"
rel="stylesheet" type="text/css" />
</head>
17
<body>
<!-- div que define estructura global de toda pantalla -->
<div id="document" >
<!-- toda pantalla tiene un banner fijo -->
<div id="header">
<div id="title">
<img src="../../public/img/hdr.title.gif"/></div>
<div id="status">
<h:form id="welcome">
#{messages['WelcomeUser']}
| <s:link id="search" action="main"
value="#{messages['Search']}" propagation="none"/>
| <s:link id="logout" action="#{login.logout}"
value="#{messages['Logout']}" />
</h:form>
</div>
</div>
<div id="headerMenu">
<div id="titleMenu"><h4>The title</h4></div>
<div id="statusMenu">
<h:form id="menuRich">
<rich:toolBar binding="#{toolBar}">
</rich:toolBar>
</h:form>
</div>
</div>
18
<!-- toda pantalla tiene un contenido variable: partes
sidebar y content deben ser definidos por c/pantalla
-->
<div id="container">
<div id="sidebar" style=" width : 150px;">
<ui:insert name="sidebar"/>
</div>
<div id="content" style="width : 500px;">
<ui:insert name="content"/>
<ui:include src="footer.xhtml" />
</div>
</div>
</div>
</body>
</html>
19
facelet: Pantalla real
facelet:
que se basa en el template
etiqueta más externa <ui:composition> indica que se usa un template
la etiqueta <ui:define> redefine partes variables del template
se diseña con <div> que tienen estilos asociados
ejemplo: password.xhtml :
<!-- librerias de etiquetas; template utilizado -->
<ui:composition 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:t="http://myfaces.apache.org/tomahawk"
xmlns:s="http://jboss.com/products/seam/taglib"
template="../common/template.xhtml">
<!-- definicion de la parte content -->
<ui:define name="content">
<div class="section"> <h1>Change Your Password</h1>
</div>
<div class="section">
...
</div>
</ui:define>
<!-- definicion de la parte sidebar -->
<ui:define name="sidebar">
<h1>changePassword use case</h1>
</ui:define>
</ui:composition>
20
Estilos asociados a los <div>
se definen en el archivo screen.css
algunos estilos:
/* para el div mas externo de una pantalla */
#document {
padding: 0 1px;
background: #fff url(../img/bg.gif) 0 0 repeat-y;
float: left;
border-bottom: 1px solid #C3BBB6;
}
/* para el banner con el menu */
#headerMenu {
float: left;
width: 100%;
height: 40px;
background: url(../img/hdr.bg.gif) 0 0 repeat-x;
}
/* para el contenido variable */
#container {
float: left;
width: 100%;
background: url(../img/hdr.bar.jpg) 0 0 repeat-x;
}
21
/* para la parte content dentro del contenido variable */
#content {
float: left;
width: 80%;
margin-top: 75px;
padding-top: 5px;
background: #fff url(../img/cnt.bg.gif) 0 0 repeat-x;
}
/* para un div section dentro de content */
#content .section {
float: left;
width: 70%;
padding: 15px 15px 0 15px;
}
/* redefine h1 dentro de div section dentro de content */
#content .section h1 {
font-family: "Trebuchet MS", Arial, sans-serif;
line-height: normal;
font-weight: normal;
font-size: large;
}
...
22
Taller en Eclipse para construir
un proyecto JSF simple
23
Creación inicial del proyecto
Registrar en Eclipse el servidor JBoss
Lanzar el servidor JBoss
Solicitar un nuevo proyecto de tipo
JSF
escoger versión "JSF 1.2 with Facelets"
y template:
"FaceletsKickStartWithoutLibs"
Ejecutar el proyecto sobre el servidor
JBoss registrado
(desde ventana: JBoss Server View)
opcion "Run on Server"
Observar validación JSF de un
elemento de edición
24
Estudiar el código fuente
Backing bean: Person.java (contiene solo un atributo: name)
Template de páginas: common.xhtml
carga archivo de propiedades internacionales :
<f:loadBundle basename="resources_es" var="msg" />
las páginas usarán esas propiedades con expresiones como
${msg.prompt}
el template también referencia hoja de estilos css o los incluye con la
etiqueta <style>
el template define 3 secciones variables que serán redefinidas por
cada página:
<ui:insert name="pageTitle">Page Title</ui:insert>
<ui:insert name="pageHeader">Page Header</ui:insert>
<ui:insert name="body">Page Body</ui:insert>
25
Paginas:
index.jsp : redirige a inputname.jsf que corresponde en realidad a
inputname.xhtml
inputname.xhtml :
redefine las secciones variables del template:
<ui:define name="pageTitle">Input User Name
</ui:define>
<ui:define name="pageHeader">
Facelets Hello Application
</ui:define>
<ui:define name="body">
…
</ui:define>
contiene forma que va a ser validada por JSF y la invocación de la
acción "greeting"
utiliza propiedades internacionales como ${msg.prompt}
greeting.xhtml : se muestra como resultado de la acción "greeting" 26
Flujo de navegación descrito en faces-config.xml:
abrirlo con el editor gráfico en ventana " Web projects" (con dobleclick invoca editor "JSF Page Flow editor")
observar declaración del backing bean y de flujo para acción
"greeting"
utiliza un lenguaje de etiquetas basado en XML:
etiqueta s <managed-bean>, <navigation-rule>
descrito en XSD (variación de un DTD): en
http://java.sun.com/xml/ns/javaee/webfacesconfig_1_2.xsd
Descriptor web.xml
abrirlo con editor "Jboss Tools XML editor"
configura el servlet JSF
sufijo real de páginas que procesará JSF: .xhtml
sufijo en los url: .jsf
27
Manejar el proyecto a través del ant
Despublicar el proyecto de JBoss
Publicar el proyecto en modo "deployed" desde el ant:
en ventana ant: añadir el build.xml del proyecto
invocar tareas: clean y deploy
Copiar el .war en el servidor :
observar el proyecto publicado en modo "exploded" directorio deploy
de JBoss
despublicarlo desde ventana: JBoss Server View (desaparece del
directorio deploy de Jboss)
sobre el war usar opcion "Deploy to Server"
observar consola
Invocar la aplicación en el navegador:
http://localhost:8080/nombreAplicacion/
28
Modificar páginas facelets
Provocar error de validación en primera página y luego
corregirlo
En la segunda página (greeting.xhtml)
agregar botón que permita navegar a la primera página
debe arreglarse reglas de navegación en faces-config
En la primera página (inputname.xhtml)
defecto: cuando se regresa con el browser de la segunda pagina a la
primera el error de validacion sigue todavía
solo se limpia cuando se navega al url de la primera página
agregar más elementos a la forma: codigo numérico de la persona
agregar este nuevo atributo al backing bean
probar validación de tipo
Agregar acción de validación especial al backing bean e
invocarlo desde botón de primera página
el codigo debe estar entre 1000 y 9000
29
Acciones de los backing beans
y mensajes construidos para el usuario
Agregar acción de validación especial al backing bean e
invocarlo desde botón de primera página
el codigo debe estar entre 1000 y 9000
public String validacionCodigo() {
if (…) {
FacesMessage message = new
FacesMessage("codigo invalido");
FacesContext.getCurrentInstance()
.addMessage("codigo", message);
return "primerapagina";
}
return "segundapagina";
}
mostrar estos mensajes
primera pagina
con etiqueta <h:messages
/> en
30
Agregar una tercera página facelet
y modificar el template
Usar ayuda de Eclipse para agregar tercera página xhtml
Agregar un botón en segunda pagina para ir a tercera página
en Jboss Tools Web >> XHTML file , usando template FaceletBlank
colocar algún elemento simple
arreglar navegacion en faces-config.xml
Modificar el template para que muestre una imagen en el
header y un texto en el footer
Todas las páginas deben usar este template
Republicar y probar
31
ANT del proyecto
32
Importancia de Ant como
manejador del proyecto
El ANT del cualquier proyecto Java es necesario para manejar
con flexibilidad todas las tareasrelacionadas con el proyecto:
compilación
empaque
publicación en el servidor
generación de documentación javadoc
generación de referencias cruzadas
testing
compilación por aspectos
...etc.
El ANT permite manejar el proyecto de forma independiente
de los ambientes de programación
33
Principales tareas del Ant
Contiene:
definición de propiedades
definición de filesets, zipefilesets, paths
principales tareas:
clean: elimina archivos generados
compile: compilación de todos los fuentes java
war: empaca las pantallas de la aplicación
ejb3: empaca todos los componentes ejb
ear: empaca toda la aplicación en un archivo .ear
deploy: publica la aplicación
testapplication: tests funcionales (con TestNG)
javadoc: genera documentación de los fuentes java
34
Ejemplo de contenido de un archivo build.xml
. . . .
<!-- GENERAL PROPERTIES ======================== -->
<!-- root directory -->
<property name="root.dir" value=".." />
<!-- external file of properties -->
<property file="build.properties" />
<!-- build directory -->
<property name="build.dir" value="build" />
<property name="classes.dir" value="${build.dir}/classes" />
. . . .
<!-- GENERAL FILESETS, ZIPFILESETS AND PATTERNSETS ==== -->
<fileset id="lib" dir="${lib.dir}">
<include name="*.jar" />
</fileset>
. . . .
<!-- classpath for compilation -->
<path id="build.classpath">
<fileset refid="lib" />
<fileset refid="el.jar" />
<fileset refid="seam.jar" />
<fileset refid="cincosoft.jar" />
</path>
. . . .
35
<!-- TARGETS ============================= -->
. . . .
<!-- compile -->
<target name="compile" depends="init" >
<echo message="property javac.debug = ${javac.debug}" />
<javac
source="1.5"
target="1.5"
destdir="${classes.dir}"
classpathref="build.classpath" debug="${javac.debug}"
deprecation="${javac.deprecation}" nowarn="on” >
<src path="${src.java.dir}" />
<src path="${src.test.dir}" />
</javac>
</target>
<!-- WAR building -->
<target name="war" depends="compile">
. . . .
<echo message="Building the war " />
<jar destfile="${build.dir}/${application.name}.war">
<fileset refid="index" />
<zipfileset refid="application.war.docroot" />
. . .
<zipfileset dir="${build.dir}">
<include name="WEB-INF/web.xml" />
<include name="WEB-INF/components.xml" />
</zipfileset>
</jar>
</target>
36
<!-- EJB3 building -->
<target name="ejb3" depends="compile">
<echo message="Building the jar of ejbs" />
<jar jarfile="${build.dir}/${application.name}.jar">
<fileset refid="application.classes" />
<fileset refid="application.ejb3.root" />
</jar>
</target>
<!-- EAR building -->
<target name="ear" depends="ejb3, war" >
<echo message="Building the ear " />
<jar destfile="${build.dir}/${application.name}.ear">
<fileset refid="seam.jar" />
. . .
<fileset refid="application.ejb3.lib" />
<zipfileset dir="${build.dir}">
<include name="${application.name}.jar" />
</zipfileset>
<zipfileset dir="${build.dir}">
<include name="${application.name}.war" />
</zipfileset>
<zipfileset refid="application.ear.resources" />
<zipfileset refid="application.configuration" />
</jar>
</target>
37
<!-- deploy -->
<target name="deploy" depends="ear" >
<copy file="${build.dir}/${application.name}.ear"
todir="${deploy.dir}" />
</target>
<!-- javadoc -->
<target name="javadoc">
<mkdir dir="${javadoc.dir}" />
<javadoc classpathref="build.classpath" destdir="${javadoc.dir}"
use="true" protected="true" version="true"
windowtitle="Documentation of ${Name}"
Overview="${overview.dir}/overview.html"
doctitle="${Name} Application Documentation"
link="${javadoc.link}” >
<packageset dir="${src.java.dir}" defaultexcludes="yes">
<include name="**/project/**" />
</packageset>
</javadoc>
<copy file="${overview.dir}/overview.html”
todir="${javadoc.dir}" />
</target>
•mirar más tareas descritas en el manual de ANT: http://ant.apache.org/index.html
•estudiar ANT del proyecto facelets y agregar publicación en el servidor
38
Descargar