Title: Apache Struts
1JakartaStrutsFramework
2Contenido
- Patrón de diseño MVC
- El framework Apache Struts
- Instalación
- Flujo de control en Struts
- Procesamiento de peticiones
- Control de errores
- Manejo de Formularios
- Librerías de etiquetas de Struts
- Internacionalización
- Ejemplo de aplicación Struts
3Modelos de desarrollo de aplicaciones web en Java
- Los servlets son buenos ejecutando lógica de
negocio, pero no son tan buenos presentando
información - JSPs son muy buenos presentando pero pésimos
introduciendo lógica programática en ellos - La combinación Servlet/JSPs es lo más común hoy
en día en el desarrollo de aplicaciones web - Dos arquitecturas
- Model-1.5 JSPs para presentación y control y
JavaBeans para la lógica - Model-2 Model-View-Controller
JavaBeans-JSPs-Servlets - MVC es tan común que se han desarrollado varias
infraestructuras en torno a este patrón de
diseño - Apache Struts
- Java Server Faces
4Arquitectura Model 1.5
5Arquitectura Model 2
6Modelo MVC
7ImplementaciónMVC en Java
- El Controlador (Controller)
- Servlet central recibe peticiones, procesa URL
recibida y delega procesamiento a JavaBeans - Servlet guarda resultado de procesamiento
realizado por JavaBeans en el contexto de la
petición, la sesión o la aplicación - Servlet transfiere control a un JSP que lleva a
cabo la presentación de resultados
8ImplementaciónMVC en Java
- El Modelo (Model)
- JavaBeans (o EJBs para aplicaciones más
escalables) juegan el rol de modelo - Algunos beans ejecutan lógica
- Otros guardan datos
- Normalmente
- Servlet controlador invoca un método en bean
lógico y éste devuelve un bean de datos - Autor de JSP tiene acceso a bean de datos
9ImplementaciónMVC en Java
- La Vista (View)
- Rol ejecutado por JSPs
- Servlet Controlador transfiere control al JSP
después de haber guardado en un contexto el
resultado en forma de un bean de datos - JSP usa jspuseBean y jspgetProperty para
recuperar datos y formatear respuesta en HTML o
XML
10ImplementaciónMVC en Java
- En resumen
- Los beans (o EJBs) ejecutan la lógica de negocio
y guardan los resultados - Los JSPs proveen la información formateada
- Los servlets coordinan/controlan la ejecución de
los beans y los JSPs
11Qué son los Frameworks?
- Los frameworks pueden ser vistos como
implementaciones de patrones de diseño que
facilitan la reutilización de diseño y código - Dado que MVC ha sido utilizado en muchas
aplicaciones web, el desarrollo de frameworks que
den soporte a áreas comunes en todas las
aplicaciones MVC es necesario - Apache Struts es una de estas frameworks
- Aplicaciones basadas en Struts consistirán de
- Código Java
- Deployment descriptors que configuran el
framework para el uso de nuestra aplicación
12Apache Jakarta Struts
- Implementación del modelo 2/patrón de diseño MVC
que facilita la creación de aplicaciones web en
Java - Creada por Craig McClanahan y donada a la Apache
Software Foundation en el 2000 (pertenece a
Apache Jakarta)
13Qué proporciona Struts?
- Un servlet (ActionServlet) que actúa como
controlador MVC totalmente configurable - Clases base que son extendidas para implementar
la lógica de la aplicación web - Struts Action
- Struts ActionForm
- Un rico conjunto de etiquetas personalizadas JSP
que cooperan con el controlador para su uso en la
capa view de MVC - Varias opciones para la validación de entrada de
usuario en formularios HTML ActionForm o
Validator Framework - Mecanismos para el manejo y reporte de errores
- Soporte para la internacionalización (i18n) a
través de ficheros de recursos y Java Locales - Soporte para fuentes de datos
- Y más ..
14Documentación y ejemplos de Struts
- En el directorio webapps de la distribución de
Struts 1.1 se pueden encontrar varios ficheros
.war muy útiles - struts-documentation.war
- En el subdirectorio api/index.html se puede
encontrar JavaDoc de Struts API - Si se ejecuta esta aplicación web en
http//localhost8080/struts-documentation/ se
puede también obtener información detallada sobre
el uso de Struts - Ejemplos de uso de Struts
- struts-example.war
- struts-blank.war ? base para la creación de
cualquier aplicación que use Struts - etc.
15Flujo de Control en Struts I
16Flujo de Control en Struts II
17Flujo de control en Struts III
- La clase org.apache.struts.action.ActionServlet
es el eje de Struts. Dada una petición de entrada
HTTP - Crea un objeto ActionForm donde guarda y valida
los parámetros de entrada - Decide que objeto Action se debe invocar y le
pasa el objeto ActionForm creado - Transfiere control a la siguiente etapa de
procesamiento de la petición (típicamente un
JSP). - El fichero de configuración web.xml contiene los
url mappings para enviar las peticiones de
llegada al ActionServlet, mientras que el fichero
de configuración de Struts struts-config.xml
contiene los mappings a acciones - Los form beans creados por ActionServlet deben
ser implementados por el programador, extendiendo
org.apache.struts.action.ActionForm. - El programador deberá definir un conjunto de
getters y setter y sobreescribir los métodos
validate() y reset() - Los objetos Action invocados deben ser
desarrollados por el programador y extienden
org.apache.struts.action.Action. Tienen un método
execute() o (perform() en Struts 1.0) que ejecuta
la lógica de negocio - La acción devuelve un objeto ActionForward al
servlet que especifica el siguiente paso a
ejecutar, normalmente se transfiere el control a
un JSP para que visualice los resultados.
18Pasos a seguir en el desarrollo de una aplicación
en Struts
- Diseña la aplicación en términos de las acciones,
vistas y estados del modelo - Añade las librerías Java de Struts y los .tlds de
sus etiquetas personalizadas a tu proyecto - Configura tu web.xml para que envíe peticiones
HTTP al ActionServet - Configura el ActionServlet definiendo elementos
ltaction-mappingsgt y ltform-beansgt en
struts-config.xml - Define tus clases Action
- Define tus clases ActionForm
- Define clases adicionales Java representando la
lógica de negocio - Define tus páginas de presentación JSP
- Explotar la aplicación
- La aplicación ejemplo suministrada con Struts,
struts-blank.war, es normalmente un buen punto de
partida para desarrollar una nueva aplicación
usando Struts
19Actions en Struts
- Se crea una acción extendiendo la clase
org.apache.struts.action.Action - El ActionServlet ejecuta acciones invocando el
método execute() tu clase Action - El método execute() contiene código para
manipular el modelo - Dentro del método execute() tienes acceso a
- Cabeceras y parámetros de peticiones HTTP
- Atributos/beans guardados en los contextos
application/session/request scope - Struts ActionForm asociados con la acción
(opcional) - El ActionMapping associado a esta acción
(opcional) - El objeto httpResponse
- El método execute() devuelve un objeto
ActionForward que indica al ActionServlet a dónde
transferir el control a continuación
20Form Beans
- Un ActionForm es un JavaBean con propiedades que
corresponden a los controles de un formulario
HTML. Los parámetros son mapeados a propiedades
del bean. - Proveen un mecanismo de buffer/validate/convert
que necesitamos para asegurarnos que el usuario
introduce los datos esperados - Actúa como puente entre el navegador y el objeto
de negocio - El programador define un form bean extendiendo la
clase org.apache.struts.action.ActionForm (o de
forma declarativa usando org.apache.struts.action.
DynaActionForm) - Hay que definir cada una de las propiedades en la
clase y escribir los getters/setters
correspondientes, siguiendo las reglas de
JavaBeans - Después de escribir el código del form bean, es
necesario asociarlo con una o más acciones a
través del fichero de configuración de Struts
struts-config.xml - Cada vez que se llama a la acción , el
ActionServlet poblará las propiedades con los
valores de los parámetros recibidos en el
formulario HTML - Las propiedades no sólo pueden ser escalares sino
que también pueden ser colecciones de valores
21Por qué se necesitan Forms Beans?
- Por qué no simplemente se accede a los
parámetros de una petición, en vez de usar un
form bean como intermediario? - Razones
- Los Form beans pueden ser validados antes de que
una acción sea invocada - Si la propiedad validate de un elemento Action en
el fichero struts-config.xml contiene el valor
true (por defecto), el método validate será
invocado - Si un form bean falla en la validación puede
hacer que Struts envíe al usuario de vuelta a la
vista (JSP) desde la que se realizó el POST en
primer lugar, junto con un mensaje de error - Es importante asignar a la propiedad input del
elemento action en struts-config.xml una
referencia a la vista que entregó el formulario - Los form beans pueden ser usados por múltiples
acciones o incluso una aplicación completa - Si se configura al ActionController para que
guarde un form bean en el contexto de sesión se
permitirá el uso del form bean en todas las
peticiones web que llegan a la aplicación
22Dynamic Action Forms
- Son ActionForms creados de manera declarativa en
struts-config.xml - Una o varias propiedades dinámicas pueden ser
pasadas a una instancia de org.apache.struts.actio
n.DynaActionForm - ltform-bean namecheckoutForm
- typeorg.apache.struts.action.DynaActionFor
mgt - ltform-property namefirstName
- typejava.lang.String/gt
- ltform-property namelastName
- typejava.lang.String/gt
- ltform-property nameage typejava.lang.Integ
er - initial18/gt
- lt/form-beangt
23Recursos de String/Manejo de Errores
- Recursos de String
- Todos los strings usados en mensajes en JSPs
tanto de datos de aplicación como de errores
puedes ser colocados en un ficheros de recursos
(ApplicationResources.properties) - Struts proporciona etiquetas personalizadas JSP
tags para acceder a estos recursosltbeanmessage
key"prompt.goodguess.heading"/gt - Manejo de errores
- Se recomienda que el manejo de errores se lleve a
cabo dentro del método execute() y el control se
transfiera a la vista apropiada - errors.add("passphrase",new ActionError("error.pas
sphrase.required")) - Struts proporciona un mecanismo separado para
permitir la implementación de un manejador global
de excepciones - Struts proporciona etiquetas JSP que ayudan en la
visualización de los errores en tu
JSPlthtmlerrors propertypassphrase/gt
24Internationalization i18n
- Struts soporta internacionalización a través de
ficheros de recursos, sus librerías de etiquetas
personalizadas y Java Locales - Se pueden definir strings a visualizar en tu
fichero de recursos, y luego ser usados en tus
JSPs - Los strings del idioma por defecto se guardan en
el fichero ApplicationResources.properties - Otros ficheros de recursos adicionales pueden ser
definidos que incluyen el idioma a usar en el
nombre del fichero. - Ejemplo
- ApplicationResources_eu.properties (Contiene
mensajes en Euskera) - ApplicationResources_es.properties (Contiene
mensajes en Castellano) - Para cambiar el idioma preferido en IE
Tools?Internet Options?Languages - Los navegadores envían la cabecera HTTP
Accept-Language en cada petición que indica cuál
es el idioma preferido por el usuario - Los ficheros de recursos deben colocarse en un
lugar accesible desde el CLASSPATH de la
aplicación web, por ejemplo, debajo del
directorio WEB-INF/classes
25Ejemplo web.xml de aplicación usando Struts
- ltweb-appgt
- lt!-- Action Servlet Configuration --gt
- ltservletgt
- ltservlet-namegtactionlt/servlet-namegt
- ltservlet-classgtorg.apache.struts.action.ActionSe
rvletlt/servlet-classgt - ltinit-paramgt
- ltparam-namegtapplicationlt/param-namegt
- ltparam-valuegt
- com.develop.ejsp.struts.re
sources.ApplicationResources - lt/param-valuegt
- lt/init-paramgt
- ltinit-paramgt
- lt! etc. --gt
- lt/init-paramgt
- ltload-on-startupgt1lt/load-on-startupgt
- lt/servletgt lt!-- Action Servlet Mapping --gt
- ltservlet-mappinggt
- ltservlet-namegtactionlt/servlet-namegt
- lturl-patterngt.dolt/url-patterngt
26Configurando Struts
- Como en todo framework se minimiza el código Java
a escribir y se maximiza la configuración a
través de ficheros XML - Struts se configura a través struts-config.xml
- Leído por el framework cuando arranca
- Contiene
- Fuentes de datos (data-sources)
- Form beans, variaciones de JavaBeans.
- Ejecutan una petición basado en una entrega de un
formulario. - Son poblados por el controlador con los datos del
formulario - Llevan a cabo validación de datos
- Son procesados por objetos Action
- Global forwards y
- ActionMappings
- Mapean el nombre de una acción a un objeto Action
27Ejemplo struts-config.xml I
- ltstruts-configgt
- ltdata-sourcesgt
- ltdata-sourcegt
- ltset-property property "autoCommit"
value"false"/gt - ltset-property property "description"
value"MessageBoard"/gt - ltset-property property "driverClass"
value"..SQLServerDriver"/gt - ltset-property property "maxCount" value"4"/gt
- ltset-property property "minCount" value"2"/gt
- ltset-property property"password" value""/gt
- ltset-property property "url"value"someurl"/gt
- ltset-property property "user"
value"someuser"/gt - lt/data-sourcegt
- lt/data-sourcesgt
- lt!-- Form Bean Definitions --gt
- ltform-beansgt
- ltform-bean name"SigninForm"
- type "com.develop.ejsp.struts.be
ans.SigninForm"/gt - lt/form-beansgt
- lt!-- Global Forward Definitions --gt
28Ejemplo struts-config.xml II
- lt!-- Action Mapping Definitions --gt
- ltaction-mappingsgt lt!-- Process a user logon
--gt - ltaction path"/SigninAction
- type "com.develop.ejsp.struts.actio
ns.SigninAction - name"SigninForm"
- scope"session
- input"/signin.jsp"gt
- ltforward name"succeeded"
path"/groups.jsp"/gt - ltforward name"failed"
path"/groups.jsp"/gt - lt/actiongt
- ltaction path"/GotoReplyToAction
- type "com.develop.ejsp.struts.actio
ns.GotoMessageAction"gt - ltforward name"succeeded"
path"/newmessage.jsp"/gt - ltforward name"failed"
path"/groups.jsp"/gt - lt/actiongt
- lt/action-mappingsgt
- lt/struts-configgt
29Procesamiento de una petición en Struts I
- Si el cliente envía la petición
- http//server/app/GotoReplyToAction.do
- El ActionServlet de Struts quita la extensión
(.do) y mira la acción correspondiente en el
fichero de configuración Struts para la acción
GotoReplyToAction - Si la encuentra encontrará o creará una instancia
del tipo (type) indicado com.develop.ejsp.strut
s.actions.GotoMessageAction - El método perform() en Struts 1.0 (o execute() en
Struts 1.1 y sucesivos) será invocado en el
objeto GotoMessageAction - Este es el lugar donde la lógica de negocio de la
petición es ejecutada
30Procesamiento de petición en Struts II
- public class GotoMessageAction
- extends org.apache.struts.action.Action
-
- public ActionForward execute(
- ActionMapping mapping,
- ActionForm actionForm,
- HttpServletRequest request,
- HttpServletResponse response)
- throws IOException, ServletException
-
- // lots of code omitted for clarity, but
here the - // business logic should be implemented
- ActionForward af mapping.findForward("succeede
d") - return af
-
-
31Procesamiento de petición en Struts III
- De los cuatro parámetros recibidos en execute(),
ActionMapping y ActionForm son específicos a
Struts - El objeto ActionMapping contiene información de
configuración proveniente de struts-config.xml
file. - El objeto ActionForm contiene el bean del
formulario que fue inicializado por el
ActionServlet al procesar la petición
32Procesamiento de petición en Struts IV
- En el mapeo de la acción GotoReplyToAction hay
dos posibles forward definidos - Uno con el nombre "succeeded" y otro
- "failed
- Si el método execute() se completa sin errores el
método ActionMapping.findForward() es llamado,
pasando el nombre del siguiente recurso a llamar. - El método findForward() devuelve un objeto
ActionForward que es pasado al ActionServlet - El objeto ActionForward contiene detalles de a
dónde debería el ActionServlet enviar la petición
(contiene el path del JSP que va a visualizar los
resultados)
33Manejo de errores en Struts I
- Struts define la clase ActionErrors que mantiene
una colección de objetos ActionError. - ActionErrors errors new ActionErrors()
- errors.add (ActionErrors.GLOBAL_ERROR,
- new ActionError("error.signing.connect
")) - saveErrors(request,errors)
- return (new ActionForward (mapping.findForward(fa
iled"))) - El código añade un sólo objeto ActionError a la
colección, pero si se llevase a cabo validación
de los campos de un formulario varios errores
podrían ser mostrados. - Luego devuelve una instancia de ActionForward que
redirige a "failed". - El ActionServlet guardará en el objeto request el
objeto ActionErrors bajo un nombre bien conocido
por Struts - request.setAttribute( Action.ERROR_KEY, errors)
- Este objeto ActionErrors es ahora disponible a
cualquier página o acción consecutiva. - La página JSP failed anterior debería tener un
área donde se mostrasen los errores producidos. - El string usado para construir un objeto
ActionError no es un mensaje de error sino que un
identificador de un recurso (i18n Struts)
34Manejo de errores en Struts II
- public class GotoMessageAction extends
org.apache.struts.action.Action - public ActionForward execute(ActionMapping
mapping, - ActionForm
actionForm, -
HttpServletRequest request, -
HttpServletResponse response) - throws IOException, ServletException
- ActionErrors errors new ActionErrors()
- try
- // business logic omitted for clarity
- catch(SQLException e)
- errors.add(ActionErrors.GLOBAL_ERROR,
- new ActionError("error.sqlerror"))
-
- if (!errors.empty())
- saveErrors(request, errors)
- ActionForward af mapping.findForward("f
ailed") - return af
-
35Manejo de Formularios I
- La otra acción definida en el fichero de
configuración de Struts era - ltaction path"/SigninAction" type"com.develop.ej
sp.struts. actions.SigninAction"
name"SigninForm" scope"session"
input"/signin.jsp"gt - ltforward name"succeeded" path"/groups.jsp"/gt
- ltforward name"failed" path"/groups.jsp"/gt
- lt/actiongt
- Esta acción está asociada con el formulario
llamado SigningForm, también definido en el
fichero de configuración - ltform-beansgt
- ltform-bean name"SigninForm" type"com.develop.e
jsp.struts. beans.SigninForm"/gt - lt/form-beansgt
36Manejo de Formularios II
- Si una acción tiene un formulario asociado a ella
(atributo name en action mapping), el
ActionServlet crea un form bean - Todo form bean hereda de org.apache.struts.action.
ActionForm, que es un JavaBean serializable. - Dos métodos en ActionForm pueden ser
sobreescritos - validate() y
- reset()
37Manejo de Formularios III
- public ActionErrors validate(ActionMapping
mapping, - HttpServletRequest
request) - ActionErrors errors new ActionErrors()
- if ((username null) (username.length() lt
1)) - errors.add ("username",
- new ActionError("error.username.required"))
- if ((password null) (password.length() lt
1)) - errors.add("password",
- new ActionError("error.password.required"))
- return errors
-
- El FormBean es poblado por el ActionServlet con
los parámetros de la petición de entrada llamando
a los métodos setXXX() correspondientes. - Una vez poblado, el form bean es validado
- Si el objeto ActionErrors devuelto es null o
vacío significa que la validación tuvo éxito y
una instancia del form bean creado, en este caso
SigningForm, es pasado al objeto SigningAction - Si la validación falla, la petición será
re-direccionada por Struts a la página que
contenía el formulario inicialmente el
formulario, dada por el atributo input del
elemento action en struts-config.xml
38Manejo de Formularios IV
- public class SigninForm extends ActionForm
- String userName null
- String password null
- public SigninForm()
-
- public void setUsername(String userName)
- this.userName userName
-
- public String getUserName()
- return this.userName
-
- public void setPassword(String password)
- this.password password
-
- public String getPassword()
39Manejo de Formularios V
- public ActionErrors validate(ActionMapping
actionMapping, -
HttpServletRequest httpServletRequest) - ActionErrors errors new ActionErrors()
- if ((password null)
(password.length() lt 1)) - errors.add("password", new
ActionError("error.password.required")) - if ((userName null)
(userName.length() lt 1)) - errors.add("username", new
ActionError("error.username.required")) - return errors
-
- public void reset(ActionMapping actionMapping,
- HttpServletRequest
httpServletRequest) - username ""
- password""
-
40Manejo de Formularios VI
- public class SigninAction
- extends org.apache.struts.action.Action
-
- public ActionForward perform(ActionMapping
mapping, -
ActionForm form, -
HttpServletRequest request, -
HttpServletResponse response) - throws IOException, ServletException
-
- try
- String username
((SigninForm) form). getUserName() - String password
((SigninForm) form). getPassword() - // etc.
-
-
-
41DataSources en Struts
- try
- DataSource ds servlet.findDataSource(null)
- message new Message()
- message.getMessage(ds,
- request.getParameter(
Message.MESSAGE_ID)), - request.getParameter( GROUP_ID_NAME))
-
- El código arriba muestra otra característica de
Struts, la habilidad de configurar y usar
referencias a javax.jdbc.DataSources - El extracto de struts-config.xml anteriormente
mostrado tiene una sección ltdata-sourcesgt para
configurar las data sources de la aplicación. - Struts provee las clases GenericDataSource y
GenericConnection que son wrappers sobre los
objetos JDBC Connections y DataSources definidos
en el fichero de configuración.
42Struts Tag Libraries
- Documentadas en http//www.onjava.com/lpt/a/4034
- La framework Struts proporciona un conjunto de 6
librerías de etiquetas, que asisten en la tarea
de la creación de la vista de MVC para evitar
incluir código Java en los JSPs - Bean Tags
- HTML Tags
- Logic Tags
- Nested Tags
- Template Tags
- Tiles Tags
43HTML Tags
- Estas etiquetas son principalmente usadas para
- Crear formularios de entrada de datos y
- Otras utilidades para visualizar interfaces
basados en HTML. - Algunas de las acciones más útiles son
- base ? genera un elemento HTML ltbasegt
- errors ? condicionalmente visualiza un conjunto
acumulado de mensajes de error - form ? define un formulario de entrada
- text ? visualiza un campo de entrada de tipo
texto - messages ? condicionalmente visualiza un conjunto
de mensajes acumulados - submit ? visualiza un botón de entrega
- Etc.
44Logic Tags
- Usadas para
- Iterar sobre colecciones
- Generación condicional de salida, y
- Flujo de aplicación
- Algunas de las acciones más útiles son
- present ? genera el contenido de marcado dentro
de esta etiqueta si el valor indicado es
encontrado en esta petición - notPresent ? lo opuesto a present
- iterate ? repite el contenido anidado dentro de
esta etiqueta al iterar sobre una colección - forward ? transfiere control a la página
especificada por la entrada ActionForward. - Etc.
45Tiles Tags (Framework)
- La librería de etiquetas Tiles es un
super-conjunto de la librería Templates - Intenta evitar la duplicación de contenido de
lenguaje de marcado dentro de una aplicación web
con respecto al look-and-feel de un portal - Un mecanismo normalmente utilizado es usar la
directiva jspinclude para añadir cabeceras/menús
y pies de páginas a un portal web - Tiles reduce el tamaño de código redundante en
una aplicación web y separa el contenido de la
visualización del mismo de manera más eficiente - Tiles define Layout Managers para JSPs
- Su objetivo principal es evitar en los JSPs
contenido de marcado que corresponda con el
look-and-feel del portal ? factoriza este
marcado, de tal manera que la modificación del
layout sea sencilla y eficiente
46Mi primera aplicación con Apache Struts
- Aplicación para llevar a cabo login
- Una vez que el usuario ha hecho login las páginas
cambian para indicar tal circunstancia - Consiste de dos pantallas
- Página Welcome que saluda al usuario y ofrece
enlaces a la aplicación - Página Logon que permite al usuario introducir
username y password - Esta página lleva a cabo la validación que los
datos introducidos son correctos
47Welcome.html
- ltHTMLgt
- ltHEADgt
- ltTITLEgtWelcome World!!lt/TITLEgt
- ltbase href"http//localhost8080/logon/pages/Welc
ome.jsp"gt - lt/HEADgt
- ltBODYgt
- ltH3gtWelcome World!lt/H3gt
- ltULgt
- ltLIgtlta href"/logon/logon.do"gtSign inlt/agtlt/LIgt
- lt/ULgt
- ltIMG src'struts-power.gif' alt'Powered by
Struts'gt - lt/BODYgt
- lt/HTMLgt
48Welcome.jsp I
- lt_at_ taglib uri"/tags/struts-bean" prefix"bean"
gt - lt_at_ taglib uri"/tags/struts-html" prefix"html"
gt - lt_at_ taglib uri"/tags/struts-logic"
prefix"logic" gt - ltHTMLgt
- ltHEADgt
- ltTITLEgtWelcome World!!lt/TITLEgt
- lthtmlbase/gt
- lt/HEADgt
- ltBODYgt
- ltlogicpresent name"user"gt
- ltH3gtWelcome ltbeanwrite name"user"
property"username"/gt!lt/H3gt - lt/logicpresentgt
- ltlogicnotPresent scope"session" name"user"gt
- ltH3gtWelcome World!lt/H3gt
- lt/logicnotPresentgt
- lthtmlerrors/gt
- ltULgt
- ltLIgtlthtmllink forward"logon"gtSign
inlt/htmllinkgtlt/LIgt - ltlogicpresent name"user"gt
49Welcome.jsp II
- lthtmlbase/gt garantiza que referencias a imágenes
o otros recursos son relativas a la localización
del JSP - ltlogicpresent name"user"gt
- ltH3gtWelcome ltbeanwrite name"user"
property"username"/gt!lt/H3gt - lt/logicpresentgt
- Esta etiqueta personalizada asegura que el
usuario solamente es saludado si ha efectuado
login - ltlogicnotPresentgt tiene el comportamiento
opuesto - ltLIgtlthtmllink forward"logon"gtSign
inlt/htmllinkgtlt/LIgt - Struts reescribe automáticamente los enlaces para
mantener la sesión del usuario. También permite
dar a los enlaces un nombre lógico y luego
guardar los enlaces reales en un fichero de
configuración.
50Logon.html
- ltHTMLgt
- ltHEADgt
- ltTITLEgtSign in, Please!lt/TITLEgt
- lt/HEADgt
- ltBODYgt
- ltform name"logonForm" method"POST"
action"/logon/LogonSubmit.do"gt - ltTABLE border"0" width"100"gt
- ltTRgt
- ltTH align"right"gtUsernamelt/THgt
- ltTD align"left"gtltinput type"text"
name"username" value""gtlt/TDgt - lt/TRgt
- ltTRgt
- ltTH align"right"gtPasswordlt/THgt
- ltTD align"left"gtltinput type"password"
name"password" value""gtlt/TDgt - lt/TRgt
- ltTRgt
- ltTD align"right"gtltinput type"submit"
name"submit" value"Submit"gtlt/TDgt - ltTD align"left"gtltinput type"reset" name"reset"
value"Reset"gtlt/TDgt - lt/TRgt
51Logon.jsp I
- lt_at_ taglib uri"/tags/struts-html" prefix"html"
gt - ltHTMLgt
- ltHEADgt
- ltTITLEgtSign in, Please!lt/TITLEgt
- lt/HEADgt
- ltBODYgt
- lthtmlerrors/gt
- lthtmlform action"/LogonSubmit"
focus"username"gt - ltTABLE border"0" width"100"gt
- ltTRgt
- ltTH align"right"gtUsernamelt/THgt
- ltTD align"left"gtlthtmltext property"username"/gtlt
/TDgt - lt/TRgt
- ltTRgt
- ltTH align"right"gtPasswordlt/THgt
- ltTD align"left"gtlthtmlpassword
property"password"/gtlt/TDgt - lt/TRgt
- ltTRgt
- ltTD align"right"gtlthtmlsubmit/gtlt/TDgt
52Logon.jsp II
- lt_at_ taglib uri"/tags/struts-html"
prefix"html"gt - La librería de etiquetas html definida por Struts
es disponible a la página - lthtmlerrors/gt garantiza si ha habido algún error
durante el login, que estos errores sean
visualizados - lthtmlform action"/LogonSubmit"
focus"username"gt - Produce un formulario HTML para la entrada de
datos. También genera JavaScript para mover el
cursor al campo username del formulario - La propiedad action hace referencia a un
componente ActionMapping en el fichero de
configuración de Struts ? dice al formulario que
JavaBean (derivado de ActionForm) debe usar para
poblar los controles de HTML.
53Logon.jsp III
- lthtmltext property"username"/gt
- Crea un control de entrada HTML para un campo de
texto. Asignará a este campo la propiedad
username del JavaBean de ayuda antes mencionado. - lthtmlpasswordgt crea un campo de entrada
- lthtmlsubmitgt y lthtmlresetgt generan botones HTML
Submit y Reset. Dos objetos serán invocados
cuando se usen estos botones - ActionForm
- Action
54Configuración de la acción logon I
- Configuración para la pantalla de logon
- JSP hace referencia al /LogonSubmit ActionMapping
- ActionMapping hace referencia a los objetos
- app.LogonForm ? describe propiedades usadas por
el formulario logon - app.LogonAction ? lleva a cabo el procesamiento
del formulario
55Configuración de la acción logon II
- lthtmlform action"/LogonSubmit"
focus"username"gt - La configuración asociada al atributo acción en
Struts sería - ltaction path"/LogonSubmit"
- type"app.LogonAction"
- name"logonForm"
- scope"request"
- validate"true"
- input"/pages/Logon.jsp"/gt
- path ? identicador único para el mapping
- type ? acción a invocar cuando el formulario es
entregado - name ? el helper JavaBean (ActionForm) a usarse
con el formulario HTML - scope ? indica en qué contexto debe guardarse el
ActionForm - validate ? indica si es necesario invocar al
método validate del ActionForm antes de invocar
al objeto Action - input ? indica a donde ir si validate devuelve
falso - ltform-bean name"logonForm"
- type"app.LogonForm"/gt
- Este extracto del fichero de configuración
relaciona el nombre lógico logonForm con la clase
app.LogonForm
56LogonForm un ejemplo de un ActionForm
- public ActionErrors validate(ActionMapping
mapping, - HttpServletRequest request)
- ActionErrors errors new ActionErrors()
- if ((username null) (username.length() lt
1)) - errors.add ("username",
- new ActionError("error.username.required"))
- if ((password null) (password.length() lt
1)) - errors.add("password",
- new ActionError("error.password.required"))
- return errors
-
- Si validate no devuelve null, entonces el
ActionController servlet guardará el objeto
ActionErrors devuelto en el contexto request,
bajo una clave conocida por la etiqueta
htmlerrors - Los tokens error.username.required y
error.password.required son claves que son
utilizadas para mirar los strings
correspondientes en el fichero de recursos de
Struts - Recordar que cada Locale contiene su propio
fichero de recursos lo que hace que los mensajes
sean fácilmente localizables.
57LogonAction un ejemplo de un LogonAction I
- package app
- import java.io.IOException
- import javax.servlet.ServletException
- import javax.servlet.http.HttpServletRequest
- import javax.servlet.http.HttpSession
- import javax.servlet.http.HttpServletResponse
- import org.apache.struts.action.Action
- import org.apache.struts.action.ActionError
- import org.apache.struts.action.ActionErrors
- import org.apache.struts.action.ActionForm
- import org.apache.struts.action.ActionForward
- import org.apache.struts.action.ActionMapping
- import org.apache.struts.action.ActionServlet
- public final class LogonAction extends Action
- // Validate credentials with business tier
- public boolean isUserLogon (String username,
- String password) throws
UserDirectoryException - return (UserDirectory.getInstance().isValidPassw
ord(username,password))
58LogonAction un ejemplo de un LogonAction II
- public ActionForward perform(ActionMapping
mapping, ActionForm form, HttpServletRequest
request, HttpServletResponse response) - throws IOException, ServletException
- // Obtain username and password from web tier
- String username ((LogonForm)
form).getUsername() - String password ((LogonForm)
form).getPassword() - // Validate credentials
- boolean validated false
- try
- validated isUserLogon(username,password)
- catch (UserDirectoryException ude)
- // couldn't connect to user directory
- ActionErrors errors new ActionErrors()
- errors.add (ActionErrors.GLOBAL_ER
ROR, new ActionError("error.logon.connect")) - saveErrors(request,errors)
- // return to input page
- return (new ActionForward
(mapping.getInput())) -
- // Save our logged-in user in the session,
because we use it again later. - HttpSession session request.getSession()
59LogonAction un ejemplo de un LogonAction III
- // Validate credentials
- boolean validated false
- try
- validated isUserLogon(username,password)
- catch (UserDirectoryException ude)
- // couldn't connect to user directory
- ActionErrors errors new ActionErrors()
- errors.add (ActionErrors.GLOBAL_ERROR,
- new ActionError("error.logon.connect"))
- saveErrors(request,errors)
- // return to input page
- return (new ActionForward(mapping.getInput()))
-
- Si un error es encontrado mientras se lleva a
cabo la validación de la entrada del usuario y
una excepción es lanzada, entonces el error es
transformado en un ActionError y el control es
devuelto a la página de entrada. Lo mismo se
lleva a cabo si se puede contactar al servicio de
directorio pero el login del usuario no es
correcto - return (mapping.findForward (Constants.WELCOME))
- Un objeto de tipo ActionForward será devuelto al
ActionServlet si todo va bien. En este caso se
envía control al forward success declarado en el
fichero de configuración como - ltforward namesuccess
- path/pages/Welcome.jsp/gt
60Referencias
- URLs
- http//jakarta.apache.org/Struts
- http//theserverside.com
- http//paginaspersonales.deusto.es/dipina/ Página
de Diego López de Ipiña. - Libros
- Programming Jakarta Struts de OReilly
- Mastering Tomcat Development de WILEY
- Java Server Programming J2EE Edition de Wrox