04 actions

Post on 05-Jul-2015

606 views 1 download

Transcript of 04 actions

mayo de 2005

Control de flujo en base a “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

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)

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)

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");

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

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

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

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.

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)

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”

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>

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>

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"));

}}

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>

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>

Ejemplo 1:Resultados

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

Ejemplo 1:Resultados (II)

Página de resultados: Tras introducir cualquier cosa

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

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>

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>

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"));}

}}

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 username@host.Por 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

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

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" %>

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>

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>

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;}

}

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; }

}

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 ={ “emiliobotin@bsch.es",

"gates@microsoft.com",“ortega@inditex.com","ellison@oracle.com" };

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() … */

}

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"));}

}}

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>

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>

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>

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>

Ejemplo 3:Resultados

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