Control de flujo en base a “Actions”


               mayo de 2005
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)
                                                                                      Struts-config.xml


                                   jsp    JSP
                                io.
                            lar
                         mu
                     for
                e st
              qu
            Re


              Envía form a hazAlgo.do
                                                               Elige        execute()         Action      Elige
                                            ActionServlet      Action                                     JSP
                                                                                              HazAlgo
                                                                                 ActionForm

Form HTML

                                                            devue
                                                                 lve   resulta
                                                                                 do



                                                                                                          JSP
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 password
    public class RegisterAction2 extends Action {
                   public ActionForward
                                  execute(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>
    <HTML>
                                                 <HEAD><TITLE></TITLE></HEAD>
    <HEAD><TITLE></TITLE></HEAD>
                                                 <BODY BGCOLOR="#FDF5E6">
    <BODY BGCOLOR="#FDF5E6">
                                                 <CENTER>
    <CENTER>
                                                 <H1>Password incorrecto</H1>
    <H1>Dirección de email incorrecta</H1>
                                                 El password debe tener al menos 6 caracteres.
    Debe tener formato username@host.
                                                 Por favor inténtelo <A HREF="register2.jsp">
    Por favor <A HREF="register2.jsp">
                                                 de nuevo</A>.
    Intentelo de nuevo</A>.
                                                 </CENTER>
    </CENTER>
                                                 </BODY></HTML>
    </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

04 actions

  • 1.
    Control de flujoen base a “Actions” mayo de 2005
  • 2.
    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
  • 3.
    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)
  • 4.
    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)
  • 5.
    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");
  • 6.
    Flujo de control(I) Struts-config.xml jsp JSP io. lar mu for e st qu Re Envía form a hazAlgo.do Elige execute() Action Elige ActionServlet Action JSP HazAlgo ActionForm Form HTML devue lve resulta do JSP
  • 7.
    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
  • 8.
    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
  • 9.
    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.
  • 10.
    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)
  • 11.
    Ejemplo 1: Mapearresultados  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”
  • 12.
    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>
  • 13.
    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>
  • 14.
    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")); } }
  • 15.
    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>
  • 16.
    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>
  • 17.
    Ejemplo 1:Resultados  Página de inicio:  http://localhost:8080/struts-actions/register1.jsp
  • 18.
    Ejemplo 1:Resultados (II)  Página de resultados:  Tras introducir cualquier cosa
  • 19.
    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
  • 20.
    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>
  • 21.
    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>
  • 22.
    Ejemplo 2:Creamos Action  Ahora nuestro Action tiene algo de lógica  Chequea formato de dirección email  Chequea longitud mínima del password public class RegisterAction2 extends Action { public ActionForward execute(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")); } } }
  • 23.
    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> <HTML> <HEAD><TITLE></TITLE></HEAD> <HEAD><TITLE></TITLE></HEAD> <BODY BGCOLOR="#FDF5E6"> <BODY BGCOLOR="#FDF5E6"> <CENTER> <CENTER> <H1>Password incorrecto</H1> <H1>Dirección de email incorrecta</H1> El password debe tener al menos 6 caracteres. Debe tener formato username@host. Por favor inténtelo <A HREF="register2.jsp"> Por favor <A HREF="register2.jsp"> de nuevo</A>. Intentelo de nuevo</A>. </CENTER> </CENTER> </BODY></HTML> </BODY></HTML> Bad-address.jsp Bad-password.jsp
  • 24.
    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
  • 25.
    Ejemplo 3: Conform 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" %>
  • 26.
    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>
  • 27.
    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>
  • 28.
    Ejemplo 3:Creamos formbean  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; } }
  • 29.
    Ejemplo 3:Creamos beande 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; } }
  • 30.
    Ejemplo 3:Creamos “lógicade 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() … */ }
  • 31.
    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")); } } }
  • 32.
    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>
  • 33.
    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>
  • 34.
    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>
  • 35.
    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>
  • 36.
    Ejemplo 3:Resultados  Si introducimos mal dirección o password nos recordará lo introducido y nos dará sugerencias