Struts Tutorial

25
Tutorial paso a paso usando JDeveloper JesusMT José de Jesús Muñoz Torres [email protected] [email protected]

Transcript of Struts Tutorial

Page 1: Struts Tutorial

Tutorial paso a paso usando JDeveloper JesusMT

José de Jesús Muñoz Torres [email protected] [email protected]

Page 2: Struts Tutorial

2

Validación yAction Forms Gracias a Struts, la programación de validación de datos de entrada puede lograrse en un tiempo mucho más corto. Cuando el usuario envía una forma, Struts encapsula los parámetros de request en un JavaBean llamado action form. Debido a que un action form es un JavaBean a menudo se le llama Form Bean, nosotros le llamaremos “Action form”. Un action form debe heredar la clase org.apache.struts.action.ActionForm. Un action form tiene cero o muchas propiedades. Una propiedad que pueda leerse debe tener un método get y una propiedad que pueda ser modificada debe tener un método set. Cada propiedad en una clase action form corresponde a un campo en la forma HTML desplegada en el explorador del usuario. Una propiedad del action form y sus campos asociados deben tener el mismo nombre. Supongamos que tenemos la siguiente forma HTML en el explorador. <form action=”/actionPath”> Nombre del producto: <input type=”text” name=”nombreProducto”/><br/> Descripción: <input type=”text” name=”descripcion”/><br/> <input type=”submit”/> </form>

Y que se ha definido la siguiente clase action form llamada FormaProducto: import org.apache.struts.action.ActionForm; public final class FormaProducto extends ActionForm { private String nombreProducto; private String descripcion; public String getNombreProducto(){

return nombreProduct; } public void setNombreProducto(String nombreProducto) { this.nombreProducto = nombreProducto; } public String getDescripcion(){ return descripcion; } public void setDescripcion(String descripcion){ this.descripcion = descripcion; }

}

Cuando la forma HTML se envía, struts crea una instancia de FormaProducto y la llena sus propiedades. La propiedad nombreProducto va a tener el valor de lo que

Page 3: Struts Tutorial

3

el usuario haya escrito en el control nombreProducto; el valor de la propiedad descripcion tendrá el mismo valor que el usuario escribió en el control descripcion. Para permitir a struts crear el action form correcto, registras el nombre lógico y el typo Java del action form usando el elemento form-bean en el archivo de configuración de struts, asi: <form-bean name=”formaProducto” type=”myPaquete.FormaProducto”>

El atributo name es un identificador o nombre lógico para el action form a través de toda la aplicación. De modo que, este nombre debe ser único. El atributo type contiene el nombre completo de la clase Java que representa al action form. Puedes tener tantos elementos form-bean como quieras. Todos ellos deben tener sub-elementos del elemento form-bean: <struts-config> <form-beans> <form-bean name=”formaProducto” type=”myPaquete.FormaProducto”/> <!-- Aquí van mas elementos form-bean --> </form-beans> </struts/config> Para hacer que struts genere un action form para una acción en particular, se usa el atributo name del elemento action que representa esa acción. Por ejemplo, si quieres crear un formaProducto cada vez que la acción guardarProducto se invoca, escribes el siguiente elemento en el archivo struts-config.xml: <action path=”guardarProducto” type=”unaClaseAccion” name=”formaProducto”/>

Una instancia de miPaquete.FormaProducto será creado para esa acción y esta instancia será pasada al método execute en el objeto acción creado para esa acción. El método execute de la clase org.apache.struts.action.Action tiene como parámetro un ActionForm. En la clase acción, se puede hacer un cast del objeto ActionForm al tipo de acción propio (Ya que un action form siempre hereda de org.apache.struts.action.ActionForm) y accesar sus propiedades. Por ejemplo: FormaProducto formaProducto = (FormaProducto) forma; String nombreProducto = formaProducto.getNombreProducto(); String descripcion = formaProducto.getFormaProducto();

Claro qu se pueden obtener los valores de nombreProducto y descripción través de parámetros con getParameter, pero veremos cual es la razón de que se usen action forms.

Page 4: Struts Tutorial

4

La clase ActionForm La clase org.apache.struts.action.ActionForm es un JavaBean asociado con una forma HTML. Cada propiedad en una acción representa un campo en la forma HTML. La propiedad name debe ser la misma que la del campo asociado. Se sobreescribe el método reset de ActionForm para inicializar los valores de las propiedades de la forma. Obsérvese que el método reset no puede ser usado para reiniciar los valores de la forma HTML asociada. Se escriben reglas de validación sobreescribiendo el método validate del ActionForm. El método validate tiene la sintaxis: public ActionErrors validate(ActionMapping mapping,

javax.servlet.ServletRequest request)

donde ActionErrors es una colección que puede contener objetos ActionError. La validación tiene éxito si el método validate devuelve null o un objeto ActionErrors vacío. Si devuelve un ActionErrors no vacío la validación ha fallado. Por ejemplo, si has definido que para añadir un producto, nombreProducto y descripcion no deben estar vacías, se pueden escribir las siguientes reglas de validación: public ActionErrors validate(ActionMapping mapping,

javax.servlet.ServletRequest request) { ActionErrors actionErrors = new ActionErrors(); If (nombreProducto.equals(“”)){ ActionErrors.add(…); } If (descripcion.equals(“”)) { ActionErrors.add(…); } return actionErrors; }

Si la validación es exitosa, el contro se cederá al objeto acción de la acción. Si ha fallado, el control se devuelve al recurso especificado en el atributo input del elemento de acción dado. Si no hay atributo input, el usuario verá un mensaje de error. Cuando se trabaja con action forms, se usan los siguientes atributos en el elemento acción: name, input, scope, validate. El servlet acción de struts hace lo siguiente cuando se invoca una acción.

Page 5: Struts Tutorial

5

1. Si el atributo name de la acción está presente, se crea una instancia de

ActionForm. El nombre de la clase puede obtenerse del elemento form-bean correspondiente.

2. Se almacena la instancia de ActionForm ya sea en un objeto request o en un objeto HttpSession, dependiendo del valor del atributo scope del elemento action. Si el atributo scope no se encuentra, la instancia se almacenará como un atributo de un objeto request.

3. Se llena la forma con parametros del objeto request llamando al método getParameterValues del objeto request.

4. A menos que el atributo validate de un action sea false, validar la forma llamando el método validate de la forma. Si el método devuelve un objeto ActionErros no vacío, almacenar el objeto ActionErrors como un atributo de typo request.

5. Si la validación es exitosa llamar al método execute del objeto action asociado, si hay alguno, y redirigir el control a la vista. Si la validación falla, devolver el control al recurso especificado en el atributo input del elemento action.

Usando Action Forms Como ejemplo de cómo usar los Action Forms generemos una aplicación usada para añadir un producto. Hay dos actions en esta aplicación, desplegarFormaParaAnadirProducto y anadirProducto. desplegarFormaParaAnadirProducto despliega una forma para añadir información de un producto. El action anadirProducto almacena el producto (simulado…)

1. Generar una nueva aplicación..

Page 6: Struts Tutorial

6

2. Luego generemos un proyecto (Que se llame igual….)

3. Generemos ahora un archivo de configuración de struts. (En forma manual….

Page 7: Struts Tutorial

7

no, no es cierto…. Usemos el asistente… ) 4. Agregar nuevo elemento al proyecto app02a

5. Agregar un descriptor de aplicación struts.

Te pide dar un nombre (acepta el predeterminado.. aunque se puede cambiar haciendo algunas adecuaciones a web.xml mejor lo dejamos como estándar..)

Page 8: Struts Tutorial

8

6. Aparece la paleta de componentes struts, ¿viste…?

7. Arrastra un “Page Forward” a la pantalla de diseño , para hacer que exista un action con un solo atributo forward que envíe el control a una página jsp sin pasar por un action controler. Esta página es desplegarFormaParaAnadirProducto.jsp. Bien… hazlo ahora.. arrastra…

8. Cambia el nombre “/page1” por “/desplegarFormaParaAnadirProducto“. (No es jsp, desplegarFormaParaAnadirProducto es el nombre del action no de la página que verá el usuario) Haz doble clic en el icono y modifiquemos algunas cosas…

9. En la pantalla de Welcome.. presiona Siguiente… 10. Selecciona JSP como el tipo de página. 11. En forma automática aparece el nombre de la página (Ahora si tiene la

extensión jsp) Deja los demás valores como están y presiona Siguiente… 12. No usaremos una página para errores así que seleeciona Siguiente… 13. En el paso 4 de 5 nos pide seleccionar que marcas (tags) usaremos.

Ninguna… damos terminar..

Page 9: Struts Tutorial

9

14. Diseñemos nuestra página JSP, arrastremos desde la paleta HTML Forms y HTLM Common algunos elementos para que quede así: a. Insertemos de la paleta HTML forms una forma b. Como Action escribe: guardarProducto.do (las acciones de struts tienen

todas la extensión *.do (.NET tiene *.aspx, ASP tiene *.asp, PHP tiene *.php, etc… struts no se podía quedar atrás…)

c. El Method es Post d. Acepta e. Dentro del área punteada (la forma) agrega una tabla de 3x2 y quítale

los bordes. f. Añade texto en la columna de la izquierda y en la columna de la derecha

añde controles TextField con su atributo name así: i. Para el primero: nombreDelProducto. ii. Para el segundo: descripcion. iii. Para el tercero: precio. iv. Luego añade un botón reset y un submit

Si tienes dudas, va el fuente de HTML:…

<form action="guardarProducto.do" method="post"> <table cellspacing="2" cellpadding="3" border="0" width="100%"> <tr> <td width="35%">Nombre del producto:</td> <td width="65%"> <input type="text" name="nombreProducto"/> </td> </tr> <tr> <td width="35%">Descripci&oacute;n:</td> <td width="65%"> <input type="text" name="descripcion"/> </td> </tr> <tr> <td width="35%">Precio:</td> <td width="65%"> <input type="text" name="precio"/> </td> </tr> </table> <p> <input type="reset" value="Limpiar datos"/><input type="submit" value="Aceptar"/> </p> </form>

Page 10: Struts Tutorial

10

15. Generemos ahora nuestra clase Bean que será el transporte del objeto

producto esto es.. ProductoTO.java

16. Generemos un nuevo archivo *.java

Page 11: Struts Tutorial

11

17. Especificamos los detalles de la nueva clase y presionamos Aceptar.

18. Inicialmente insertamos el código:

19. Esto indica que tenemos tres campos, pero son privados… necesitamos

acceder a ellos de alguna forma, eso lo hacemos con accesores, algo como: getNombreProducto y setNombreProducto. Jdeveloper ya lo hace por nosotros. Así que damos clic con el botón derecho del ratón sobre nombreProducto y seleccionamos “generate accesors”

20. Seleccionamos los tres campos y damos aceptar..

21. ¿Qué tal..? eeehhhhh… 22. Generemos ahora nuestra FormaProducto que en realidad es un JavaBean.

private String nombreProducto; private String descripcion; private String precio;

Page 12: Struts Tutorial

12

23. Seleccionamos con el botón derecho del ratón sobre la estructura del descriptor y seleccionamos “Form beans”

24. Luego insertamos un form bean

25. Y escribimos sus propiedades.

Page 13: Struts Tutorial

13

26. Ahora, generemos la clase, selecciona “Go to Form Bean Source”

27. Acepta los valores predeterminados.

28. Hagamos algo parecido a lo que hicimos con ProductoTO. Insertemos las mismas propiedades y sus accesores. g. Modifiquemos un poco el método validate:

29. Regresemos al diseño de struts config… y arrastremos un Action y un Page. 30. Demos al Action el nombre “guardarProducto” y al Page

“desplegarProductoGuardado.jsp”

public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors errores = new ActionErrors(); if(nombreProducto.equals("")){ errores.add("no.nombreProducto",new ActionMessage("No está el nombre del producto")); } if(nombreProducto.equals("")){ errores.add("no.descripcion",new ActionMessage("No está la descripción del producto")); } return errores;

}

Page 14: Struts Tutorial

14

31. Arrastra una linea “Forward” y conecta con ella al Action y al Page.

32. Observa que aparece la palabra “success” indica que cuando la acción

guardarProducto tenga éxito mostrará la página jsp de la derecha. 33. Modifica las propiedades del Action (en la ventana de la derecha) como

sigue: name : formaProducto input : /desplegarFormaParaAnadirProducto.jsp scope : request

34. Haz doble clic sobre el Action para generar la clase

“app02a.GuardarProductoAction” 35. Esta clase es un Action así que debemos escribir algo de código:

Page 15: Struts Tutorial

15

Uff!!! Que relajo… vamos… vamos… falta solo un JSP

36. Generemos ahora el JSP que muestra el resultado del guardado, haz doble

clic sobre el icono 37. Aquí necesitamos leer el objeto producto que viene viajando desde la forma,

ya existe, solo es necesario acceder a él. Para eso vamos a usar algo conocido como “Marcas” (tags) que permiten hacer uso de un “código fuente” que interactúa con Java, las bibliotecas que lo contienen y la página JSP. Añadimos la biblioteca de marcas JSTL (Java Estándar Tag Libraries).

package app02a.action; import app02a.form.FormaProducto; import app02a.to.ProductoTO; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; public class GuardarProductoAction extends Action { /**This is the main action called from the Struts framework. * @param mapping The ActionMapping used to select this instance. * @param form The optional ActionForm bean for this request. * @param request The HTTP Request we are processing. * @param response The HTTP Response we are processing. */ public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { FormaProducto formaProducto = (FormaProducto) form; ProductoTO producto = new ProductoTO(); //Generamos un objeto ProductoTO //Llenamos las propiedades del producto a partir de la forma producto.setNombreProducto(formaProducto.getNombreProducto()); producto.setDescripcion(formaProducto.getDescripcion()); producto.setPrice(formaProducto.getPrecio()); //Si necesitamos usar persistencia (es decir guardar los datos a la base de datos), la escribimos aquí... //usamos Connections, Statements, “insert into Table y todo ese rollo…. (en el siguiente tutorial… ) request.setAttribute("producto", producto); return mapping.findForward( "success"); } }

Page 16: Struts Tutorial

16

a. Seleccionamo las propiedades del proyecto:

b. Seleccionamos las bibliotecas JSTL Core 1.1

Page 17: Struts Tutorial

17

c. Esto permite que la paleta de componentes tenga los controles JSTL Core 1.1. Genera antes que nada un diseño como el que sigue:

d. Arrastra a la derecha de Detalles un tag “out” y escribe sus

propiedades:

rollo explicativo: $ indica “instrucción por evaluar”, { indica “inicia la instrucción”, producto.nombreProducto es claro, es el dato a obtener y } indica “fin de la instrucción”. Existen varias tags, te toca estudiarlas..

e. Haz lo mismo con los otros dos campos…. f. Ahora.. a correr esta aplicación… g. Selecciona de árbol de aplicaciones la página JSP que contiene la

forma para añadir productos… clic con el derecho y ruuunnnnn…. Así se ve la página inicial.. llena los datos, observa que si no llenas los campos no se va a ningún lado….

Page 18: Struts Tutorial

18

Así se ve la pantalla si llenaste los dos primeros campos … Un reto… Usar una basde de datos real..

Page 19: Struts Tutorial

19

Uso de biblioteca de marcas HTML y validación específica. El tutorial anterior no está completo debido a que no hemos visto los mensajes de error en pantalla, además los valores ya escritos no se conservan. Bien, modifiquémoslo para que tenga esas características. Para esto necesitamos usar las marcas de la biblioteca HTML, una de las tres bibliotecas que tiene struts. Comencemos… 1. Generemos una aplicación app02b, un proyecto app02b y un archivo descriptor

de struts strut-config.xml. (Como se hizo en el anterior tutorial) 2. Al insertar un descriptor struts se insertan automáticamente las bibliotecas tag

de struts. 3. Insertemos un Page Forward de la paleta de struts y seleccionemos la

biblioteca struts HTML. 4. Añade la siguiente línea a desplegarFormaParaAnadirProducto.jsp, justo debajo

de la directiva page. <%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>

5. Inserta la siguiente línea después de la marca <body> : <html:errors/> 6. Cambia la marca <input type=”Text” … por

<html:text property="nombreProducto"/> 7. Haz lo mismo con las otras dos marcas Text. 8. La marca form cámbiala por <html:form action="guardarProducto.do"> 9. De la misma manera cambia la marca de fin de forma con su correspondiente

</html:form> 10. Cambia las marcas reset y submit por

<html:reset/> <html:submit value="Añadir producto"/> 11. Puedes crear desde cero esta página, solo arrastra elementos Struts HTML en

vez de HTML forms. 12. Ahora trabajemos con los errores.

Para que un error despliegue un mensaje correspondiente hagamos lo siguiente

Page 20: Struts Tutorial

20

a. Modifiquemos FormaProducto de modo que el método validate que así:

Observa las sentencias “if”, observemos la primera… ”Si el nombreProducto es igual a “” (nada), entonces añade (errores.add) un error global de tipo action (ActionErrors.GLOBAL_ERROR), busca el mensaje “no.nombreProducto” y añádelo a la vista jsp que lo generó. ¿Y donde lo busca?.. Ahhh!! En el archivo AplicationResources.Properties que está aquí:

Observa que hay una línea de errores por cada error que necesites. No olvides agregar a la FormaProducto: import org.apache.struts.action.ActionError;

b. Ahora… a correr…..

public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors errores = new ActionErrors(); if(nombreProducto.equals("")){ errores.add(ActionErrors.GLOBAL_ERROR, new ActionError("no.nombreProducto")); } if(descripcion.equals("")){ errores.add(ActionErrors.GLOBAL_ERROR, new ActionError("no.descripcion")); } if(Double.parseDouble(precio)>100){ errores.add(ActionErrors.GLOBAL_ERROR, new ActionError("precio.caro")); } return errores; }

Page 21: Struts Tutorial

21

Otro ejemplo, obtener producto y actualizar producto

Habíamos visto que solo la segunda acción estaba asociada con una forma. Veremos como usar ahora dos acciones.

obtener producto actualizar producto

La acción obtener producto obtiene un producto de la base de datos y lo despliega en una forma. Esta forma te permite la edición de los valores. Al presionar el botón “Actualizar” se llamará a la acción actualizarProducto y veremos un mensaje que nos indica que el producto se ha actualizado. A continuación se muestra el archivo struts-config.xml, sigue su esquema para crear tu aplicación:

<?xml version = '1.0' encoding = 'windows-1252'?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration

1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"> <struts-config>

<form-beans> <form-bean name="formaProducto"

type="actualizarProductos.forma.FormaProducto"/>

</form-beans> <action-mappings>

<action path="/obtenerProducto" type="actualizarProductos.action.ObtenerProductoAction"

name="formaProducto" validate="false" scope="request"

> <forward name="success" path="/desplegarProducto.jsp"/>

</action> <action path="/actualizarProducto"

type="actualizarProductos.action.ActualizarProductoAction" name="formaProducto" validate="false" scope="request"

input="/desplegarProducto.jsp">

<forward name="success" path="/desplegarActualizado.jsp"/> </action>

</action-mappings> <message-resources parameter="actualizarProductos.mypackage.ApplicationResources"/> </struts-config>

Page 22: Struts Tutorial

22

Enseguida se muestra el contenido de obtenerProductoAction.java

Aquí tenemos el código de actualizarProductoAction.java

package actualizarProductos.action;

import actualizarProductos.forma.FormaProducto;

import actualizarProductos.to.ProductoTO;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm;

import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping;

public class ObtenerProductoAction extends Action {

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,

HttpServletResponse response) throws IOException, ServletException {

//Creamos un producto

ProductoTO producto = new ProductoTO(); producto.setNombreProducto("Equipo portátil DELL 6400");

producto.setDescripcion("Con procesador Core Duo de intel"); producto.setPrecio("17500");

//Llenamos la forma (FormaProducto, no la forma jsp, eeehhh?...)

FormaProducto forma = (FormaProducto) form;

forma.setNombreProducto(producto.getNombreProducto()); forma.setDescripcion(producto.getDescripcion());

forma.setPrecio(producto.getPrecio());

return mapping.findForward( "success"); }

}

Page 23: Struts Tutorial

23

El contenido de la página JSP productoActualizado.jsp es:

package actualizarProductos.action;

import java.io.IOException; import actualizarProductos.forma.FormaProducto;

import actualizarProductos.to.ProductoTO;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;

import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward;

import org.apache.struts.action.ActionMapping;

public class ActualizarProductoAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form,

HttpServletRequest request,

HttpServletResponse response) throws IOException,

ServletException { FormaProducto forma = (FormaProducto)form;

ProductoTO producto = new ProductoTO();

producto.setNombreProducto(forma.getNombreProducto());

producto.setDescripcion(forma.getDescripcion()); producto.setPrecio(forma.getPrecio());

request.setAttribute("producto", producto);

return mapping.findForward( "success"); }

}

Page 24: Struts Tutorial

24

Ahora, a ensamblar todo y ejecutar. Que tal…. Simple? …..

<%@ page contentType="text/html;charset=windows-1252"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <html>

<head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">

<title>untitled</title> <link href="css/jdeveloper.css" rel="stylesheet"

media="screen"/>

</head> <body><h3>

El producto ha sido actualizado </h3><hr/><p>

Detalles:

</p><p> Nombre del producto: <c:out value="${producto.nombreProducto}"/>

</p><p> Descripci&oacute;n:

<c:out value="${producto.descripcion}"/> </p><p>

Precio:

<c:out value="${producto.precio}"/> </p></body> </html>

Page 25: Struts Tutorial

25

Asistentes (Dicho de otra forma, formas multipágina….) Algunas veces, para hacer que una aplicación sea más amigable se puede dividir en varias formas pequeñas. En este caso se tendrá un action form que se mapea a múltiples formas HTML y se guarda en un objeto HttpSession (durante todo la vida de la sesión). Generemos otra aplicación que se usará para almacenar información de empleados, se usarán 3 formas. La primera obtiene el puesto del empleado, la segunda el nombre del empleado y la tercera su dirección. Se hará una llamada a una acción guardarEmpleado y se enivará una página de confirmación. Aquí se muestra la estructura del directorio que contiene nuestra aplicación en Jdeveloper. Paso a paso…. 1. Generemos una aplicación llamada AsistenteEmpleados con un prefijo de

paquete empleado, un proyecto agregarEmpleados y un archivo descriptor de struts (¿te acuerdas que es eso….?)

2. Comencemos por crear nuestro Bean de empleado en el paquete to, llamémosle EmpleadoTO y generemos los accesores para los campos: puesto, nombre, apellidop, apellidom, direccion1 y direccion2 todos de tipo String.

3. Genera una FormaEmpleado y genera lo necesario en el descriptor dentro de la marca form-beans, añade los campos que añadiste en EmpleadoTO y genera sus accesores.

4. Ahora generemos los elementos struts como sigue: Agrega 3 pageForward y un action. Los atributos name de cada elemento son “formaEmpleado”, scope es “Session”. El atributo forward de page1 es page1, de page2 es page2, de page3 es page3, finalmente el elemento forward de page4 es page4.jsp y el elemento type de page4 es la accion agregarEmpleadoAction.