04 actions

36
mayo de 2005 Control de flujo en base a “Actions”

Transcript of 04 actions

Page 1: 04 actions

mayo de 2005

Control de flujo en base a “Actions”

Page 2: 04 actions

Introducción (I)

Actions clases más flexibles Responsabilidades:

Acceder a capa de negocio Preparar los objetos de datos para capa de presentación Tratamiento de errores

¿Dónde encaja un Action ? ActionForward proporciona un enlace a página de entrada ActionForm captura la entrada ActionMapping configura el Action Action envía la entrada a la base de datos

Page 3: 04 actions

Introducción (II)

¿Qué son? Son miniservlets. El servlet ActionServlet “reparte el juego” entre los

actions Se fija en los ActionMapping para enviar a uno u otro

Todo Action devuelve un ActionForward El ActionServlet hace la redirección a la página adecuada

Multihilo Sólo se instancia una clase Action de cada tipo por aplicación

Punto de entrada de ejecución Método perform() (Struts 1.0) ó método execute()

(desde 1.1)

Page 4: 04 actions

Introducción (III)

¿Qué parámetros aceptan? mapping ActionMapping utilizado para

invocar este Action form ActionForm especificado (si lo hay) en

el ActionMapping request El contexto del request (mismo que

en Servlet) Response Contexto del response (mismo que

en Servlet)

Page 5: 04 actions

Introducción (IV)

¿Qué funciones tienen? Validar precondiciones

Validaciones no realizadas en ActionForm. P.e.: ¿Está usuario logeado?

Llamar a los métodos de lógica de negocio Buena práctica separar de Action lógica de negocio

Tratamiento de errores Registrar errores. Objetos ActionErrors, ActionError y

método saveErrors Mostrar mensaje de error “localizado”

Rutar el control a la vista adecuada return mapping.findForward("continue");

Page 6: 04 actions

Flujo de control (I)

JSP

ActionServlet

JSP

Form HTML

ActionHazAlgo

ActionForm

Request form

ulario.jsp

Envía form a hazAlgo.doElige

Action

execute() EligeJSP

devuelve resultado

Struts-config.xml

Page 7: 04 actions

Flujo de control (II) Usuario solicita un formulario HTML Formulario le envía a hazAlgo.do

Struts-config.xml mapea /hazAlgo.do a HazAlgoAction (derivada de Action)

Se invoca método execute() de HazAlgoAction Como argumento va ActionForm con datos del formulario El objeto Action HazAlgoAction invoca lógica de negocio y/o accede

al modelo (BBDD) Action utiliza método mapping.findForward para buscar recurso

(definido en struts-config.xml) a dónde redireccionar (JSP, otro Action, página HTML, etc.)

Struts redirecciona a salida adecuada Si es JSP se pueden usar tags de struts <bean:message> para

internacionalizar salida y <bean:write> para escribir variables

Page 8: 04 actions

Escribiendo una aplicación (I)

Modificar struts-config.xml: Relacionar paths XXXX.do a clases Action Especificar condiciones de retorno a

páginas JSP Declarar todos los form beans utilizados

(ActionForm) Definir un ActionForm

Clase derivada de ActionForm que contiene datos de un formulario HTML

Page 9: 04 actions

Escribiendo una aplicación (II)

Crear JavaBeans de resultados: Contendrán los resultados de la capa de negocio

y/o del modelo

Definir una clase Action que reciba las peticiones:

struts-config.xml determina: Entrada: puede haber varias URIs mapeadas a un mismo

Action Salida: a qué JSP se devolverá el control dependiendo de

estado: éxito, error en BBDD, error autenticación, etc.

Page 10: 04 actions

Escribiendo una aplicación (III)

Crear el formulario que invoca a hazAlgo.do: El atributo action de formulario HTML apunta a hazAlgo.do Pueden usarse Tags de Struts para facitar tarea <html:form>

Mostrar resultados en JSP Se utilizan tags de Struts <bean:write> para copiar valores de

JavaBean de resultados en página Alternativamente puede usarse JSLT

Si la página JSP sólo es accesible desde Action pueden ir dentro de WEB-INF

Si JSP tiene sentido como página accesible directamente puede hacerse redirect (petición pasa por cliente) en vez de forward (petición no pasa por cliente):

<forward ... redirect="true"/> (en struts-config.xml)

Page 11: 04 actions

Ejemplo 1: Mapear resultados

Aplicación básica de registro Familiarización con Actions No se comprobará entrada Mapeo de datos

Localización http://localhost:8080/struts-actions

Clase Action RegisterAction1

Dentro de paquete app Siempre devuelve página de éxito.

Creamos proyecto en NetBeans “struts-actions” partiendo de fuentes de directorio “struts-actions”

Page 12: 04 actions

Ejemplo 1:struts-config.xml (I)

Creamos entrada para register1.do Creamos entrada <action> dentro de <action-mappings> Notas sobre atributos de action:

Path: Es el path que se quiere maper al action Es relativo al contexto de la aplicación. NO incluye el .do Path=“/register1” http://localhost:8080/struts-actions/register1.do

Type: Es la clase Action a la que se mapea URI

<action-mappings><action path="/register1"

type=“app.RegisterAction1“</action>

</action-mappings>

Page 13: 04 actions

Ejemplo 1:struts-config.xml (II)

Especificamos página de retorno Creamos entrada <forward> con nombre “success” Dos alternativas

Página “privada” para un action concreto Se define anidado dentro de la etiqueta <action> correspondiente

Página accesible desde más de un action o recurso. Se define dentro de <global-forwards> fuera de <action-mappings>

Definimos la página de retorno como “global”: Dentro de directorio WEB-INF No será accesible desde el navegador

directamente

<global-forwards><forward name=“success“

path=“/WEB-INF/results/confirm.jsp"></forward>

</global-forwards>

Page 14: 04 actions

Ejemplo 1:Creamos Action Todas deben derivar de Action Deben ir todas en el mismo paquete El método principal a redefinir es execute().

Está relacionado con nuestra lógica de negocio No requiere declaraciones en struts-config.xml

Siempre debería acabar con mapping.findForward Puede haber diferentes retornos dependiendo del éxito de la acción La elección del JSP específico de acuerdo con el estado de salida se definía en struts-config.xml (podemos cambiar JSPs sin

tener que recompilar) Por ahora no usaremos SuggestionBean

package app;

import javax.servlet.http.*;import org.apache.struts.action.*;

public class RegisterAction1 extends Action {public ActionForward execute(ActionMapping mapping,

ActionForm form,HttpServletRequest request,HttpServletResponse response)

throws Exception {return(mapping.findForward("success"));

}}

Page 15: 04 actions

Ejemplo 1:Presentación

Tenemos lógica básica Falta parte de presentación Formulario que apunte a register1.do Página de entrada: register1.jsp:

<HTML><HEAD><TITLE></TITLE></HEAD><BODY BGCOLOR="#FDF5E6"><CENTER><H1>Registro de nueva cuenta</H1><FORM ACTION="register1.do" METHOD="POST"> Dirección Email: <INPUT TYPE="TEXT" NAME="email"><BR> Password: <INPUT TYPE="PASSWORD" NAME="password"><BR> <INPUT TYPE="SUBMIT" VALUE="Registrar"></FORM></CENTER></BODY></HTML>

Page 16: 04 actions

Ejemplo 1:Presentación (II) Página de resultado Se realiza forward dentro del servidor No interesa que sea accesible directamente

La creamos dentro de WEB-INF Página WEB-INF/results/confirm.jsp que sólo muestra mensaje de éxito

<HTML><HEAD><TITLE></TITLE></HEAD><BODY BGCOLOR="#FDF5E6"><CENTER><H1>Ha registrado la cuenta con éxito</H1>Felicidades.</CENTER></BODY></HTML>

Page 17: 04 actions

Ejemplo 1:Resultados

Página de inicio: http://localhost:8080/struts-actions/register1.jsp

Page 18: 04 actions

Ejemplo 1:Resultados (II)

Página de resultados: Tras introducir cualquier cosa

Page 19: 04 actions

Ejemplo 2: Múltiples resultados

Extensión de aplicación de ejemplo 1 Mapear más de un resultado según condición de

error

Nueva clase Action: RegisterAction2

Devolverá “success”, “bad-address” o “bad-password”

Nuevas páginas de resultados WEB-INF/result/bad-address.jsp WEB-INF/result/bad-password.jsp

Page 20: 04 actions

Ejemplo 2: Entrada

Reaprovechamos register1.jsp para register2.jsp

Cambiamos ACTION del formulario que apunte a: register2.do

<HTML><HEAD><TITLE>New Account Registration</TITLE></HEAD><BODY BGCOLOR="#FDF5E6"><CENTER><H1>Registro de nueva cuenta (2ª forma)</H1><FORM ACTION="register2.do" METHOD="POST"> Dirección Email: <INPUT TYPE="TEXT" NAME="email"><BR> Password: <INPUT TYPE="PASSWORD" NAME="password"><BR> <INPUT TYPE="SUBMIT" VALUE="Registrar"></FORM></CENTER></BODY></HTML>

Page 21: 04 actions

Ejemplo 2: struts-config.xml

Añadimos nuevo action (register2.do) Tiene varias salidas dependiendo del

resultado de la operación

<action-mappings><action path="/register2"

type="coreservlets.RegisterAction2">

<forward name="bad-address"path="/WEB-INF/results/bad-address.jsp"/>

<forward name="bad-password"path="/WEB-INF/results/bad-password.jsp"/>

<forward name="success"path="/WEB-INF/results/confirm.jsp"/>

</action></action-mappings>

Page 22: 04 actions

Ejemplo 2:Creamos Action

Ahora nuestro Action tiene algo de lógica Chequea formato de dirección email Chequea longitud mínima del passwordpublic class RegisterAction2 extends Action {

public ActionForwardexecute(ActionMapping mapping,

ActionForm form,HttpServletRequest request,HttpServletResponse response)

throws Exception {String email = request.getParameter("email");String password = request.getParameter("password");if ((email == null) || (email.trim().length() < 3) || (email.indexOf("@") == -1)) {

return(mapping.findForward("bad-address"));} else if ((password == null) || (password.trim().length() < 6)) {

return(mapping.findForward("bad-password"));} else {

return(mapping.findForward("success"));}

}}

Page 23: 04 actions

Ejemplo 2:Presentación Páginas de salida de error que muestren mensajes adecuados:

WEB-INF/result/bad-address.jsp WEB-INF/result/bad-password.jsp

<HTML><HEAD><TITLE></TITLE></HEAD><BODY BGCOLOR="#FDF5E6"><CENTER><H1>Dirección de email incorrecta</H1>Debe tener formato [email protected] favor <A HREF="register2.jsp">Intentelo de nuevo</A>.</CENTER></BODY></HTML>

<HTML><HEAD><TITLE></TITLE></HEAD><BODY BGCOLOR="#FDF5E6"><CENTER><H1>Password incorrecto</H1>El password debe tener al menos 6 caracteres.Por favor inténtelo <A HREF="register2.jsp">de nuevo</A>.</CENTER></BODY></HTML>

Bad-address.jsp Bad-password.jsp

Page 24: 04 actions

Ejemplo 2:Resultados Accedemos a: http://localhost:8080/struts-actions/register2.jsp Páginas de error en caso de introducir mal email o password menor de 6

caracteres

Page 25: 04 actions

Ejemplo 3: Con form beans

Partimos de Ejemplo2 Añadimos sugerencias para el usuario en caso de que no complete

algún campo Utilizaremos un form bean

Contiene los datos que recibimos del formulario Familiarización de uso de ActionForms

Utilizaremos un bean de resultados Representa resultados del modelo o lógica de negocio

Haremos uso de tags para JSP de struts <bean:write> nos facilitará el manejo de campos de los beans Para poder utilizar los tags <bean:xxxxx> ha de incluirs en el JSP:

<%@ taglib uri=http://struts.apache.org/tags-bean prefix="bean" %>

Page 26: 04 actions

Ejemplo 3:struts-config.xml (I)

Definimos el form bean a utilizar: Creamos entrada <form-bean> con nombre

“userFormBean” Parámetros

Name: nombre simbólico que se referenciará en actions Type: clase que implementa el ActionForm

<form-beans><form-bean name=“userFormBean“

type=“app.UserFormBean"></form-bean>

</form-beans>

Page 27: 04 actions

Ejemplo 3:struts-config.xml (II)

Definimos un nuevo action (register3.do) con dos nuevos argumentos

Name: nombre simbólico que hace referencia al form-bean definido (ActionForm)

Scope: Ámbito donde es válido el form-bean. Por defecto es session. Ponemos request (se inicialicen los datos con cada envío).

<action path="/register3"type=“app.RegisterAction3"name="userFormBean"scope="request“><forward name="bad-address"

path="/WEB-INF/results/bad-address-tags.jsp"/><forward name="bad-password"

path="/WEB-INF/results/bad-password-tags.jsp"/><forward name="success"

path="/WEB-INF/results/confirm.jsp"/></action>

Page 28: 04 actions

Ejemplo 3:Creamos form bean

Definimos un form bean básico Clase derivada de ActionForm Debe tener parámetros mutables que se correspondan con campos

del formulario HTML Debe tener parámetros leibles para cada uno que quiera mostrarse

en el JSP de salida

package app;import org.apache.struts.action.*;public class UserFormBean extends ActionForm {

private String email = "";private String password = "";public String getEmail() { return(email); }public void setEmail(String email) {

this.email = email;}public String getPassword() { return(password); }public void setPassword(String password) {

this.password = password;}

}

Page 29: 04 actions

Ejemplo 3:Creamos bean de resultados

Definimos el bean de resultados Está relacionado con nuestra lógica de negocio No requiere declaraciones en struts-config.xml

package app;import org.apache.struts.action.*;public class SuggestionBean {

private String email = "";private String password = "";

public SuggestionBean(String email, String password){this.email = email;this.password = password;

}public String getEmail() { return this.email; }public String getPassword() { return this.password; }

}

Page 30: 04 actions

Ejemplo 3:Creamos “lógica de negocio”

Definimos una clase que implemente nuestra lógica de negocio

Podría hacer cualquier cosa Clase de ayuda que nos sugiera combinaciones

usuario/password

package app;public class SuggestionUtils {

private static String[] suggestedAddresses ={ “[email protected]",

"[email protected]",“[email protected]","[email protected]" };

private static String chars ="abcdefghijklmnopqrstuvwxyz0123456789#@$%^&*?!";

public static SuggestionBean getSuggestionBean() {String address = randomString(suggestedAddresses);String password = randomString(chars, 8);return(new SuggestionBean(address, password));

}/* … Mirar código ejemplo para randomString() … */

}

Page 31: 04 actions

Ejemplo 3:Creamos action Partimos del Action del ejemplo anterior

Ahora recuperamos los datos de entrada del ActionForm (en vez del request) Metemos bean SuggestionBean como atributo del objeto request como

resultado en las páginas de error.

public class RegisterAction2 extends Action {public ActionForward

execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response)

throws Exception {UserFormBean userBean = (UserFormBean) form;String email = userBean.getEmail();String password = userBean.getPassword();if ((email == null) || (email.trim().length() < 3) || (email.indexOf("@") == -1)) {

request.setAttribute("suggestionBean",SuggestionUtils.getSuggestionBean());

return(mapping.findForward("bad-address"));} else if ((password == null) || (password.trim().length() < 6)) {

request.setAttribute("suggestionBean",SuggestionUtils.getSuggestionBean());

return(mapping.findForward("bad-password"));} else {

return(mapping.findForward("success"));}

}}

Page 32: 04 actions

Ejemplo 3:Presentación

El punto de entrada: register3.jsp Igual sólo que apunta a register3.do

<HTML><HEAD><TITLE>New Account Registration</TITLE></HEAD><BODY BGCOLOR="#FDF5E6"><CENTER><H1>Registro de nueva cuenta (con sugerencias)</H1><FORM ACTION="register3.do" METHOD="POST"> Dirección Email: <INPUT TYPE="TEXT" NAME="email"><BR> Password: <INPUT TYPE="PASSWORD" NAME="password"><BR> <INPUT TYPE="SUBMIT" VALUE="Registrar"></FORM></CENTER></BODY></HTML>

Page 33: 04 actions

Ejemplo 3:Presentación (II) Salida

Hacemos uso de tag <bean:write>. Por defecto filtra caracteres malignos y los convierte a código HTML. Podemos evitar el filtrado con argumento: filter=“false”

“>” “&gt; Para hacer uso de los tags <bean:XXXX> hay que importar:

<%@ taglib uri="http://struts.apache.org/tags-bean"prefix="bean" %>

Podemos referencias los beans (tanto los normales como ActionForms) por su nombre (especificado en sruts-config.xml)

Creamos WEB-INF/results/bad-address-tags.jsp

<HTML><HEAD><TITLE>New Account Registration</TITLE></HEAD><BODY BGCOLOR="#FDF5E6"><CENTER><H1>Registro de nueva cuenta (con sugerencias)</H1><FORM ACTION="register3.do" METHOD="POST"> Dirección Email: <INPUT TYPE="TEXT" NAME="email"><BR> Password: <INPUT TYPE="PASSWORD" NAME="password"><BR> <INPUT TYPE="SUBMIT" VALUE="Registrar"></FORM></CENTER></BODY></HTML>

Page 34: 04 actions

Ejemplo 3:Presentación (III) Salida

Hacemos uso de tag <bean:write>. Por defecto filtra caracteres malignos y los convierte a código HTML. Podemos evitar el filtrado con argumento: filter=“false”

“>” “&gt; Para hacer uso de los tags <bean:XXXX> hay que importar:

<%@ taglib uri="http://struts.apache.org/tags-bean"prefix="bean" %>

Podemos referencias los beans (tanto los normales como ActionForms) por su nombre (especificado en sruts-config.xml)

Creamos WEB-INF/results/bad-address-tags.jsp

<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><TITLE>Illegal Email Address</TITLE></HEAD><BODY BGCOLOR="#FDF5E6"><CENTER><H1>Email incorrecto</H1>La dirección "<bean:write name="userFormBean" property="email"/>"debe tener el formato usuario@host (p.e. "<bean:write name="suggestionBean" property="email"/>")<p>Inténtelo <A HREF="register3.jsp">de nuevo</A>.</p></CENTER></BODY></HTML>

Page 35: 04 actions

Ejemplo 3:Presentación (IV)

Salida Y lo mismo para WEB-INF/results/bad-

address-tags.jsp

<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><TITLE>Illegal Password</TITLE></HEAD><BODY BGCOLOR="#FDF5E6"><CENTER><H1>Password Incorrecto</H1>El password "<bean:write name="userFormBean" property="password"/>" es muy corto.Debe tener al menos 6 caracteres. P.e.: "<bean:write name="suggestionBean" property="password"/>"Por favor inténtelo <A HREF="register3.jsp">de nuevo</A>.</CENTER></BODY></HTML>

Page 36: 04 actions

Ejemplo 3:Resultados

Si introducimos mal dirección o password nos recordará lo introducido y nos dará sugerencias