Está en la página 1de 63

4.

4 Tutorial de Jakarta Struts

Qu es Struts ?
n

Framework OpenSource para implementar aplicaciones web con servlets y JSP segn el patrn arquitectnico Model-View-Controller Subproyecto de Jakarta
n

Autor principal: Craig R. McClanahan

n n

Funciona sobre cualquier servidor de aplicaciones web que implemente las APIs de servlets y JSP Julio 2001: versin 1.0 Ha ganado gran relevancia en el mundo de las aplicaciones web Java Paquetizado en un fichero .jar

Qu proporciona Struts ?
n n

Un servlet Front Controller y clases relacionadas Un gran nmero de acciones JSP


n n

View Helpers La mayor parte de las que se necesitan en una situacin real Implementa javax.sql.DataSource

Un pool genrico de conexiones a una BD relacional


n

El patrn Front Controller en Struts (1)


javax.servlet.http.HttpServlet

org.apache.struts.action.ActionServlet
0..n

org.apache.struts.action.Action + perform

# doGet # doPost <<use>> <<instantiate>>

org.apache.struts.action.ActionForm + reset + validate Action1 ActionN

...
ActionFormN

ActionForm1

...

<<use>>

El patrn Front Controller en Struts (2)


n

ActionServlet
n n

Servlet Front Controller En web.xml se especifica que todas las URLs que impliquen procesamiento (por GET o POST) vayan a este servlet
n

Ej.: las URLs que termine en .do

Clases ActionForm
n

Si el programador lo desea, puede acceder a los parmetros de la request a travs de un JavaBean que extiende ActionForm
n

Especialmente til en formularios

Clase Action => mtodo perform


n

Accede a los parmetros de la request, directamente o va el ActionForm correspondiente Realiza la operacin invocando un mtodo de un Session Facade del modelo o una fachada del controlador Deja el resultado devuelto por el mtodo en la request o en la sesin Devuelve un objeto ActionForward, que representa la URL que hay que visualizar a continuacin (sendRedirect o forward)

El patrn Front Controller en Struts (3)


n

Fichero de configuracin
n

Clases ActionForm que usa nuestra aplicacin


n n

Nombre lgico (ej.: loginForm) Nombre completo de la clase (ej.: es.udc.fbellas.j2ee.strutstutorial.portal3.http .view.actionforms.LoginForm) URL de tipo path relativo a contexto (ej.: /Login)
n

URLs que implican procesamiento


n

No llevan el .do final

Nombre completo de la clase Action (ej.: es.udc.fbellas.j2ee.strutstutorial.portal3.http .controller.actions.LoginAction) Nombre lgico de la clase ActionForm asociada

El patrn Front Controller en Struts (y 4)


n

Fichero de configuracin (cont)


n

Definiciones de nombres lgicos de URLs


n

n n

Nombre que usan las acciones cuando devuelven un ActionForward (ej.: ShowMainPage) sendRedirect o forward URL a invocar (ej.: /MainPage.jsp)

Cuando el servlet ActionServlet arranca (init), lee el fichero de configuracin Crea una nica instancia de cada clase Action
n

n n

No se crea una instancia de una clase Action por cada peticin que se recibe Tienen que ser thread-safe Misma situacin que cuando se trabaja con servlets

Acciones JSP
n

Bean
n

Imprimir el valor de las propiedades de JavaBeans de manera segura Soporte para internacionalizacin de mensajes Generacin de HTML bsico
n n

HTML
n

Campos de entrada en formularios Enlaces (con URL rewriting)

Logic
n n

Si mayor que, si menor que, etc. Iteracin sobre colecciones de objetos Caso particular del patrn Composite View Lo veremos con MiniBank y MiniPortal

Template
n n

Arquitectura MVC con Struts


n

Modelo
n

Clases independientes de la vista y el controlador Quizs se necesite extender el servlet ActionServlet Conjunto de clases Action Interactan con el modelo y seleccionan la siguiente vista (dejndole los datos en uno de los cuatro posibles mbitos, normalmente request o session) Conjunto de clases ActionForm Conjunto de pginas JSP
n n n

Controlador
n n n

Vista
n n

No contienen cdigo Java Slo visualizan datos Usan acciones JSP (las de Struts, las estndares y quizs algunas desarrolladas a medida) para recuperar los valores a mostrar y formatearlos

Demo Portal-3 (1)


Lanzar el navegador

Acceder a Portal-3 main page

Demo Portal-3 (2)


Clic Login

Demo Portal-3 (y 3)

Clic en Logout Terminar y lanzar el navegador dos das ms tarde

Acceder a Portal-3 main page

Portal-3 main page (Welcome to Portal-3)

Estructura de paquetes
es.udc.fbellas.j2ee.util.struts.action es.udc.fbellas.j2ee.strutstutorial.portal3 http controller actions view actionforms messages model userfacade delegate exceptions

tar tvf StrutsTutorial.war (1)


MainPage.jsp InternalError.jsp Login.jsp Index.jsp WEB-INF/Struts/struts-bean.tld WEB-INF/Struts/struts-html.tld WEB-INF/Struts/struts-logic.tld WEB-INF/Struts/struts-config.xml WEB-INF/lib/struts.jar WEB-INF/lib/crimson.jar WEB-INF/lib/jaxp.jar WEB-INF/lib/StandardUtil.jar WEB-INF/lib/WebUtil.jar

tar tvf StrutsTutorial.war (y 2)


WEB-INF/classes/es/udc/fbellas/j2ee/strutstutorial/portal3/model/ userfacade/delegate/UserFacadeDelegate.class WEB-INF/classes/es/udc/fbellas/j2ee/strutstutorial/portal3/model/ userfacade/exceptions/IncorrectPasswordException.class WEB-INF/classes/es/udc/fbellas/j2ee/strutstutorial/portal3/http/ controller/actions/LoginManager.class WEB-INF/classes/es/udc/fbellas/j2ee/strutstutorial/portal3/http/ controller/actions/LogoutAction.class WEB-INF/classes/es/udc/fbellas/j2ee/strutstutorial/portal3/http/ controller/actions/LoginAction.class WEB-INF/classes/es/udc/fbellas/j2ee/strutstutorial/portal3/http/ controller/actions/MainPageAction.class WEB-INF/classes/es/udc/fbellas/j2ee/strutstutorial/portal3/http/view/ actionforms/LoginForm.class WEB-INF/classes/es/udc/fbellas/j2ee/strutstutorial/portal3/http/view/ messages/Messages.properties WEB-INF/web.xml

Comentarios
n

WEB-INF/Struts
n

Ficheros *.tld: descriptores de las libreras de las acciones proporcionadas por Struts struts-config.xml: configuracin de Struts para la aplicacin del tutorial

WEB-INF/lib
struts.jar: ficheros .class de Struts n crimson.jar y jaxp.jar: Struts usa JAXP para parsear el fichero struts-config.xml n StandarUtil.jar y WebUtil.jar: subsistema Util de J2EE-Examples WEB-INF/classes/es/.../Messages.properties
n n

Internacionalizacin de mensajes

WEB-INF/web.xml (1)
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> <web-app> <distributable/> <!-- ========================= Servlets ========================= --> <!-- == Standard Action Servlet Configuration (with debugging) == --> <servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servletclass>

WEB-INF/web.xml (2)
<init-param> <param-name>application</param-name> <param-value>es.udc.fbellas.j2ee.strutstutorial.portal3.http. view.messages.Messages</param-value> </init-param> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/Struts/struts-config.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>2</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>2</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet>

WEB-INF/web.xml (3)
<!-- ================== Servlet mapping ========================== --> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <!-- ========================= Session ========================== --> <session-config> <session-timeout>30</session-timeout> </session-config> <!-- ======================= Welcome page ======================= --> <welcome-file-list> <welcome-file>Index.jsp</welcome-file> </welcome-file-list>

WEB-INF/web.xml (y 4)
<!-- ================= Struts Tag Library Descriptors ============ --> <taglib> <taglib-uri>/struts-bean.tld</taglib-uri> <taglib-location>/WEB-INF/Struts/struts-bean.tld</taglib-location> </taglib> <taglib> <taglib-uri>/struts-html.tld</taglib-uri> <taglib-location>/WEB-INF/Struts/struts-html.tld</taglib-location> </taglib> <taglib> <taglib-uri>/struts-logic.tld</taglib-uri> <taglib-location>/WEB-INF/Struts/struts-logic.tld</taglib-location> </taglib> </web-app>

Comentarios (1)
n

Servlet org.apache.struts.actions.ActionServlet
n

Aparecen dos tags que no hemos usado hasta ahora


n

init-param
n n

Permite definir un parmetro de configuracin y su valor Accesible va Servlet.getServletConfig().getInitParameter() Indica que el servlet se debera cargar cuando el servidor arranque la aplicacin web El valor (opcional) indica el orden relativo de carga con respecto a otros servlets (cuanto menor sea el valor, antes se carga)

load-on-startup
n

Parmetros de inicializacin
n n

Vase JavaDoc de org.apache.struts.actions.ActionServlet application


n n

Nombre del fichero de mensajes (sin sufijo .properties) Debe estar debajo de WEB-INF/classes y usar un nombre consistente con su ubicacin (como si de una clase se tratase)

Comentarios (2)
n

Servlet org.apache.struts.actions.ActionServlet
n

Parmetros de inicializacin (cont)


n

config
n

Path de tipo relativo a contexto del fichero de configuracin de Struts Nivel de detalle en los mensajes de depuracin que escribe Struts con el mtodo ServletContext.log Nivel de detalle en los mensajes de depuracin que escribe Struts en System.out

debug
n

detail
n

Comentarios (y 3)
n

Libreras de tags proporcionadas por Struts


n

Aparece un tag que no hemos usado hasta ahora, taglib, que contiene los elementos
n

taglib-uri: URI a usar en la directiva taglib de JSP (para importar la librera) taglib-location: path relativo a contexto del fichero .tld (Tag Library Descriptor) de la librera de tags

WEB-INF/Struts/struts-config.xml (1)
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_0.dtd"> <struts-config>

<!-- ============ Form Bean Definitions =========================== --> <form-beans> <form-bean name="loginForm" type="es.udc.fbellas.j2ee.strutstutorial.portal3.http.view.actionforms. LoginForm"/> </form-beans>

WEB-INF/Struts/struts-config.xml (2)
<!-- ============ Global Forward Definitions ====================== --> <global-forwards> <forward name="MainPage" path="/MainPage.do" redirect="true"/> <forward name="InternalError" path="/InternalError.jsp" redirect="true"/> </global-forwards> <!-- ============ Action Mapping Definitions ====================== --> <action-mappings> <action path="/MainPage" type="es.udc.fbellas.j2ee.strutstutorial.portal3.http.controller. actions.MainPageAction"> <forward name="ShowMainPage" path="/MainPage.jsp"/> </action> <action path="/Login" type="es.udc.fbellas.j2ee.strutstutorial.portal3.http.controller. actions.LoginAction" name="loginForm" scope="request" input="/Login.jsp" validate="true"/>

WEB-INF/Struts/struts-config.xml (y 3)
<action path="/Logout" type="es.udc.fbellas.j2ee.strutstutorial.portal3.http.controller. actions.LogoutAction"/> <!-- ================================================================= The standard administrative actions available with Struts. These must be either omitted or protected by security in a real application deployment. ================================================================ --> <action path="/admin/addFormBean" type="org.apache.struts.actions.AddFormBeanAction"/> ... <action path="/admin/removeMapping" type="org.apache.struts.actions.RemoveMappingAction"/> </action-mappings> </struts-config>

Comentarios (1)
n

Definiciones de nombres lgicos de URLs


n

Se usan en la implementacin de las acciones para devolver un ActionForward y en algunas acciones JSP Se especifican con forward
n

n n n

Atributos documentados en JavaDoc de org.apache.struts.action.ActionForward name: Nombre lgico path: path relativo a contexto de la URL a la que se invocar redirect: true (sendRedirect) o false (forward)
n

false por defecto

Pueden ser globales (global-forwards) o particulares a una accin (action)

Comentarios (y 2)
n

action
n

n n

Atributos documentados en JavaDoc de org.apache.struts.action.ActionMapping type: nombre completo de la clase Action path: URL (path relativo a contexto) que provocar la invocacin de la accin
n

Se especifican sin el sufijo .do !

name: nombre del ActionForm (definido por form-bean) que captura los parmetros de la invocacin scope: mbito (request o session) del ActionForm
n

En general, request

n n

input: path relativo a contexto del formulario de entrada validate: true si el Front Controller tiene que llamar al mtodo validate del ActionForm
n

En general, true

WEB-INF/classes/es/.../Messages.properties (1)
Buttons.login=Login ErrorMessages.loginName.notFound=Login name not found ErrorMessages.mandatoryField=Mandatory field ErrorMessages.password.incorrect=Incorrect password ErrorMessages.retry=Please, check if the operation has been performed, \ and retry if necessary errors.footer=</b></font> errors.header=<font color="red"><b> InternalError.title=Internal error

WEB-INF/classes/es/.../Messages.properties (y 2)
Login.loginName=Login name Login.password=Password Login.rememberMyPassword=Remember my password (cookies must be enabled) Login.title=Portal-3 login form MainPage.hello=Hello MainPage.login=Login MainPage.logout=Logout MainPage.title=Portal-3 main page MainPage.welcome=Welcome to Portal-3

Comentarios (1)
n

Asocia parares <identificadorMensaje, mensaje>


n n n

Convenios de nombrado para los identificadores de mensajes Ordenados alfabticamente errors.footer y errors.header son dos identificadores especiales que entiende la accin html:errors de Struts Mensajes en el lenguaje por defecto del servidor Mensajes en el lenguaje cuyo cdigo ISO es xx Cdigos ISO en http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt
n n n n

Messages.properties
n

Messages_xx.properties
n n

en: Ingls es: Espaol gl: Gallego Etc.

Comentarios (2)
n

Messages.properties slo resuelve un aspecto particular de la internacionalizacin de aplicaciones: impresin de mensajes en distintos idiomas
n

En una aplicacin ms compleja puede ser necesario tener trozos de pginas en distintos idiomas (con gran cantidad de texto esttico) y seleccionarlas o incluirlas dinmicamente desde otras en funcin del idioma Formatear y tratar fechas, horas, nmeros, cantidades monetarias
n

Otros aspectos en internacionalizacin


n

Paquetes java.text y java.util

Puede requerir tablas para almacenar contenido en distintos idiomas


n

Ej.: un servicio de noticias

es.udc.fbellas.j2ee.strutstutorial.portal3.model.userfacade.delegate

UserFacadeDelegate + UserFacadeDelegate() + login(loginName : String, password : String, passwordIsEncrypted : boolean) : void

Simula la facha del modelo que proporciona las operaciones relativas a la interaccin del usuario con el portal

es.udc.fbellas.j2ee.util.struts.action (1)

Action (from action)

DefaultAction + perform(m : ActionMapping, f : ActionForm, rq : HttpServletRequest, rp : HttpServletResponse) : ActionForward # doPerform(m : ActionMapping, f : ActionForm, rq : HttpServletRequest, rp : HttpServletResponse) : ActionForward # doOnInternalError(m : ActionMapping, f : ActionForm, rq : HttpServletRequest, rp : HttpServletResponse) : ActionForward

PropertyValidator

es.udc.fbellas.j2ee.util.struts.action (y 2)
n

DefaultAction
n

Problema
n

En general, las clases Action invocarn una operacin sobre un Business Delegate del modelo o una fachada del controlador, que puede lanzar InternalErrorException Es necesario (1) capturarla, (2) imprimirla en un log (para depuracin) y (3) ir a una pgina que indique error interno Implementa perform (Template Method) en trminos de doPerform y doOnInternalError Las clases hijas implementan doPerform, que tiene la misma signatura que perform, pero puede lanzar adicionalmente InternalErrorException

Las clases Action derivarn de DefaultAction


n

PropertyValidator
n

Clase utilidad para validar campos de entrada comunes (double, long, String, etc.)

es.udc.fbellas.j2ee.util.struts.action.DefaultAction (1)
package es.udc.fbellas.j2ee.util.struts.action; import import import import import import import import import import import java.io.IOException; javax.servlet.ServletContext; javax.servlet.http.HttpServletRequest; javax.servlet.http.HttpServletResponse; javax.servlet.ServletException; org.apache.struts.action.Action; org.apache.struts.action.ActionMapping; org.apache.struts.action.ActionForm; org.apache.struts.action.ActionForward; org.apache.struts.action.ActionError; org.apache.struts.action.ActionErrors;

import es.udc.fbellas.j2ee.util.exceptions.InternalErrorException;

es.udc.fbellas.j2ee.util.struts.action.DefaultAction (2)
public abstract class DefaultAction extends Action { public ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { try { return doPerform(mapping, form, request, response); } catch (InternalErrorException e) { return doOnInternalErrorException(mapping, form, request, response, e); } } protected abstract ActionForward doPerform(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, InternalErrorException;

es.udc.fbellas.j2ee.util.struts.action.DefaultAction (y 3)
protected ActionForward doOnInternalErrorException( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, InternalErrorException internalErrorException) throws IOException, ServletException { /* * Log error, even with debug level <= 0, because it is a * severe error. */ ServletContext servletContext = servlet.getServletConfig().getServletContext(); servletContext.log(internalErrorException.getMessage(), internalErrorException); /* Redirect to input page. */ return mapping.findForward("InternalError"); } }

es.udc.fbellas.j2ee.util.struts.action.PropertyValidator (1)

public final class PropertyValidator { private final static String INCORRECT_VALUE = "ErrorMessages.incorrectValue"; private final static String MANDATORY_FIELD = "ErrorMessages.mandatoryField"; public final static long validateLong(ActionErrors errors, String propertyName, String propertyValue, boolean mandatory, long lowerValidLimit, long upperValidLimit) { long propertyValueAsLong = 0; if (validateMandatory(errors, propertyName, propertyValue, mandatory)) { boolean propertyValueIsCorrect = true;

es.udc.fbellas.j2ee.util.struts.action.PropertyValidator (2)
try { propertyValueAsLong = new Long(propertyValue).longValue(); if ( (propertyValueAsLong < lowerValidLimit) || (propertyValueAsLong > upperValidLimit) ) { propertyValueIsCorrect = false; } } catch (NumberFormatException e) { propertyValueIsCorrect = false; } if (!propertyValueIsCorrect) { errors.add(propertyName, new ActionError(INCORRECT_VALUE)); } } return propertyValueAsLong; }

es.udc.fbellas.j2ee.util.struts.action.PropertyValidator (y 3)
public final static boolean validateMandatory(ActionErrors errors, String propertyName, String propertyValue) { if ((propertyValue == null) || (propertyValue.length() == 0)) { errors.add(propertyName, new ActionError(MANDATORY_FIELD)); return false; } else { return true; } }

// Resto de mtodos validateXXX => Anlogos ...

Comentarios
n

org.apache.struts.action.ActionMapping
n

Permite acceder a los valores configurados en strutsconfig.xml para la accin en ejecucin (inclusive a los forwards globales) Juega el papel del mapa de errores que hemos empleado en apartado anteriores El mensaje de error es un org.apache.struts.action.ActionError, que dispone de un constructor que permite especificar el identificador del mensaje de error (en Messages.properties) Representa la siguiente URL a la que hay que ir El Front Controller lo invocar despus de llamar al mtodo perform sobre la accin

org.apache.struts.action.ActionErrors
n

org.apache.struts.action.ActionForward
n n

es.udc.fbellas.j2ee.strutstutorial.portal3.http.view.actionforms.LoginForm (1)

public class LoginForm extends ActionForm { private String loginName; private String password; private boolean rememberMyPassword; public LoginForm() { reset(); } public String getLoginName() { return loginName; } public void setLoginName(String loginName) { this.loginName = loginName.trim(); }

es.udc.fbellas.j2ee.strutstutorial.portal3.http.view.actionforms.LoginForm (2)

public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public boolean getRememberMyPassword() { return rememberMyPassword; } public void setRememberMyPassword(boolean rememberMyPassword) { this.rememberMyPassword = rememberMyPassword; }

es.udc.fbellas.j2ee.strutstutorial.portal3.http.view.actionforms.LoginForm (y 3)
public void reset(ActionMapping mapping, HttpServletRequest request) { reset(); } public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors errors = new ActionErrors(); PropertyValidator.validateMandatory(errors, "loginName",loginName); PropertyValidator.validateMandatory(errors, "password", password); return errors; } private void reset() { loginName = null; password = null; rememberMyPassword = false; } }

Comentarios
n

LoginForm
n

Juega el mismo papel que la clase vista en el apartado anterior Hereda de org.apache.struts.action.ActionForm reset
n

Generalmente interesa redefinir reset y validate


n

El Front Controller lo llama antes de dar valor a las propiedades Permite validar las propiedades despus de que el Front Controller les haya dado valores Slo se invoca si se ha especificado validate="true" para la accin correspondiente en struts-config.xml Si devuelve un ActionErrors no vaco, el Front Controller (1) no invocar el mtodo perform sobre la accin correspondiente, (2) insertar un atributo con los errores en la request, y (3) har un forward a la URL que especifica el atributo input del action correspodiente en strutsconfig.xml (formulario de entrada)

validate
n

es.udc.fbellas.j2ee.strutstutorial.portal3.http.controller.actions
DefaultAction (from action)

MainPageAction

LoginAction

LogoutAction

<<use>>

<<use>>

<<use>>

LoginManager

<<use>> UserFacadeDelegate (from delegate)

es.udc.fbellas.j2ee.strutstutorial.portal3.http.controller.actions.LoginAction (1)
public class LoginAction extends DefaultAction { public ActionForward doPerform(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, InternalErrorException { /* Get data. */ LoginForm loginForm = (LoginForm) form; String loginName = loginForm.getLoginName(); String password = loginForm.getPassword(); boolean rememberMyPassword = loginForm.getRememberMyPassword(); /* Do login. */ ActionErrors errors = new ActionErrors();

es.udc.fbellas.j2ee.strutstutorial.portal3.http.controller.actions.LoginAction (y 2)
try { LoginManager.login(request, response, loginName, password, rememberMyPassword); } catch (InstanceNotFoundException e) { errors.add("loginName", new ActionError( "ErrorMessages.loginName.notFound")); } catch (IncorrectPasswordException e) { errors.add("password", new ActionError( "ErrorMessages.password.incorrect")); } /* Return ActionForward. */ if (errors.empty()) { return mapping.findForward("MainPage"); } else { saveErrors(request, errors); return new ActionForward(mapping.getInput()); } } }

es.udc.fbellas.j2ee.strutstutorial.portal3.http.controller.actions.LogoutAction
public class LogoutAction extends DefaultAction { public ActionForward doPerform(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, InternalErrorException { /* Do logout. */ LoginManager.logout(request, response); /* Return ActionForward. */ return mapping.findForward("MainPage"); } }

Comentarios
n

Las acciones utilizan el mtodo saveErrors (heredado de org.struts.apache.action.Action) para insertar un atributo con los errores en la request

MainPage.jsp (1)
<%@ taglib uri="/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/struts-html.tld" prefix="html" %> <%@ taglib uri="/struts-logic.tld" prefix="logic" %> <html> <head> <title><bean:message key="MainPage.title"/></title> </head> <body text="#000000" bgcolor="#ffffff" link="#000ee0" vlink="#551a8b" alink="#000ee0">

MainPage.jsp (2)
<%-- Welcome --%> <h1> <logic:notPresent name="loginName" scope="session"> <bean:message key="MainPage.welcome"/> </logic:notPresent> <logic:present name="loginName" scope="session"> <bean:message key="MainPage.hello"/> <bean:write name="loginName" scope="session"/> </logic:present> </h1> <%-- Some <br>'s --%> <br> <br> <br>

MainPage.jsp (y 3)
<%-- Links to Login or Logout --%> <logic:notPresent name="loginName" scope="session"> <html:link href="Login.jsp"> <bean:message key="MainPage.login"/> </html:link> </logic:notPresent> <logic:present name="loginName" scope="session"> <html:link href="Logout.do"> <bean:message key="MainPage.logout"/> </html:link> </logic:present> </body> </html>

Login.jsp (1)
<%@ taglib uri="/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/struts-html.tld" prefix="html" %> <html> <head> <title><bean:message key="Login.title"/></title> </head> <body text="#000000" bgcolor="#ffffff"> <html:form action="Login.do"> <table width="100%" border="0" align="center" cellspacing="12"> <%-- Login name --%> <tr> <th align="right" width="50%"> <bean:message key="Login.loginName"/> </th> <td align="left"> <html:text property="loginName" size="16" maxlength="16"/> <html:errors property="loginName"/> </td> </tr>

Login.jsp (2)
<%-- Password --%> <tr> <th align="right" width="50%"> <bean:message key="Login.password"/> </th> <td align="left"> <html:password property="password" size="16" maxlength="16"/> <html:errors property="password"/> </td> </tr> <%-- Remember my password --%> <tr> <th align="right" width="50%"> <bean:message key="Login.rememberMyPassword"/> </th> <td align="left"> <html:checkbox property="rememberMyPassword"/> </td> </tr>

Login.jsp (y 3)
<%-- Login button --%> <tr> <td width="50%"></td> <td align="left" width="50%"> <html:submit> <bean:message key="Buttons.login"/> </html:submit> </td> </tr> </table> </html:form> </body> </html>

Comentarios
n

html:text, html:password y html:checkbox recuperan el valor de la propiedad asociada a travs del mtodo getXXX (property="XXX") sobre la instancia de LoginForm enganchada a la request
n

Saben que el ActionForm asociado es de tipo LoginForm dado que el atributo action de html:form es igual a Login.do struts-config.xml especifica LoginForm como la clase ActionForm para la URL /Login.do Imprime el mensaje de error asociado a la propiedad especificada si figura en el ActionErrors enganchado a la request El mensaje vendr flanqueado por errors.header y errors.footer (Messages.properties)

html:errors
n

InternalError.jsp
<%@ taglib uri="/struts-bean.tld" prefix="bean" %> <html> <head> <title><bean:message key="InternalError.title"/></title> </head> <body text="#000000" bgcolor="#ffffff"> <h3><div align="center"><font color="red"> <bean:message key="InternalError.title"/>. <bean:message key="ErrorMessages.retry"/> </font></div></h3> </body> </html>

Un pequeo problema
n

Situacin
n

Imaginemos que la pgina de bienvenida fuese MainPage.jsp


n

En realidad es Index.jsp

n n

Un usuario hace el login y selecciona Remember my password Termina la sesin Accede dos das despus tecleando la URL de la aplicacin en su navegador (ej.: http://www.acme.org/MiniPortal) La sesin no contendr el atributo loginName, dado que no se ha ejecutado LoginManager.getLoginName Se le redirige a la pgina de login

Un solucin
n

El navegador nunca invocar a /MainPage.jsp directamente, sino a /Index.jsp o /MainPage.do


n

Index.jsp
n n

Pgina de bienvenida Hace un forward a /MainPage.do => se ejecuta MainPageAction LoginManager.getLoginName y forward a /MainPage.jsp

MainPageAction
n

Cuando se haga un sendRedirect a la pgina principal se har siempre con la URL /MainPage.do y nunca con /MainPage.jsp
n

/MainPage.jsp nunca aparecer en la caja de dilogo del navegador, de manera que el usuario nunca har un bookmark a esa pgina, sino a /MainPage.do o /Index.jsp

En MiniPortal volveremos a discutir este problema

es.udc.fbellas.j2ee.strutstutorial.portal3.http.controller.actions.MainPageAction
public class MainPageAction extends DefaultAction { public ActionForward doPerform(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, InternalErrorException { /* * "LoginManager.getLoginName" creates an appropriate session * if the session had expired, or the user had not logged in, * but he/she had selected "remember my password" in the last * login. */ LoginManager.getLoginName(request); /* Return ActionForward. */ return mapping.findForward("ShowMainPage"); } }

Index.jsp
<jsp:forward page="MainPage.do"/>

También podría gustarte