Está en la página 1de 25

Tutorial paso a paso usando JDeveloper

JesusMT
Jos de Jess Muoz Torres jesus@desarrolla.com.mx jjmt027@hotmail.com

Validacin yAction Forms


Gracias a Struts, la programacin de validacin de datos de entrada puede lograrse en un tiempo mucho ms corto. Cuando el usuario enva una forma, Struts encapsula los parmetros 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 mtodo get y una propiedad que pueda ser modificada debe tener un mtodo 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/> Descripcin: <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 enva, struts crea una instancia de FormaProducto y la llena sus propiedades. La propiedad nombreProducto va a tener el valor de lo que 2

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 lgico y el typo Java del action form usando el elemento form-bean en el archivo de configuracin de struts, asi:
<form-bean name=formaProducto type=myPaquete.FormaProducto>

El atributo name es un identificador o nombre lgico para el action form a travs de toda la aplicacin. 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 accin en particular, se usa el atributo name del elemento action que representa esa accin. Por ejemplo, si quieres crear un formaProducto cada vez que la accin 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 accin y esta instancia ser pasada al mtodo execute en el objeto accin creado para esa accin. El mtodo execute de la clase org.apache.struts.action.Action tiene como parmetro un ActionForm. En la clase accin, se puede hacer un cast del objeto ActionForm al tipo de accin 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 descripcin travs de parmetros con getParameter, pero veremos cual es la razn de que se usen action forms.

La clase ActionForm
La clase org.apache.struts.action.ActionForm es un JavaBean asociado con una forma HTML. Cada propiedad en una accin representa un campo en la forma HTML. La propiedad name debe ser la misma que la del campo asociado. Se sobreescribe el mtodo reset de ActionForm para inicializar los valores de las propiedades de la forma. Obsrvese que el mtodo reset no puede ser usado para reiniciar los valores de la forma HTML asociada. Se escriben reglas de validacin sobreescribiendo el mtodo validate del ActionForm. El mtodo validate tiene la sintaxis:
public ActionErrors validate(ActionMapping mapping, javax.servlet.ServletRequest request)

donde ActionErrors es una coleccin que puede contener objetos ActionError. La validacin tiene xito si el mtodo validate devuelve null o un objeto ActionErrors vaco. Si devuelve un ActionErrors no vaco la validacin ha fallado. Por ejemplo, si has definido que para aadir un producto, nombreProducto y descripcion no deben estar vacas, se pueden escribir las siguientes reglas de validacin:
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 validacin es exitosa, el contro se ceder al objeto accin de la accin. Si ha fallado, el control se devuelve al recurso especificado en el atributo input del elemento de accin 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 accin: name, input, scope, validate. El servlet accin de struts hace lo siguiente cuando se invoca una accin.

1. Si el atributo name de la accin 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 mtodo getParameterValues del objeto request. 4. A menos que el atributo validate de un action sea false, validar la forma llamando el mtodo validate de la forma. Si el mtodo devuelve un objeto ActionErros no vaco, almacenar el objeto ActionErrors como un atributo de typo request. 5. Si la validacin es exitosa llamar al mtodo execute del objeto action asociado, si hay alguno, y redirigir el control a la vista. Si la validacin falla, devolver el control al recurso especificado en el atributo input del elemento action.

Usando Action Forms


Como ejemplo de cmo usar los Action Forms generemos una aplicacin usada para aadir un producto. Hay dos actions en esta aplicacin, desplegarFormaParaAnadirProducto y anadirProducto. desplegarFormaParaAnadirProducto despliega una forma para aadir informacin de un producto. El action anadirProducto almacena el producto (simulado) 1. Generar una nueva aplicacin..

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

3. Generemos ahora un archivo de configuracin de struts. (En forma manual.

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

5. Agregar un descriptor de aplicacin struts.

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

6. Aparece la paleta de componentes struts, viste?

7. Arrastra un Page Forward a la pantalla de diseo , para hacer que exista un action con un solo atributo forward que enve el control a una pgina jsp sin pasar por un action controler. Esta pgina 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 pgina 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 pgina. 11. En forma automtica aparece el nombre de la pgina (Ahora si tiene la extensin jsp) Deja los dems valores como estn y presiona Siguiente 12. No usaremos una pgina para errores as que seleeciona Siguiente 13. En el paso 4 de 5 nos pide seleccionar que marcas (tags) usaremos. Ninguna damos terminar..

14. Diseemos nuestra pgina 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 extensin *.do (.NET tiene *.aspx, ASP tiene *.asp, PHP tiene *.php, etc struts no se poda quedar atrs) c. El Method es Post d. Acepta e. Dentro del rea punteada (la forma) agrega una tabla de 3x2 y qutale los bordes. f. Aade texto en la columna de la izquierda y en la columna de la derecha ade controles TextField con su atributo name as: i. Para el primero: nombreDelProducto. ii. Para el segundo: descripcion. iii. Para el tercero: precio. iv. Luego aade un botn 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>

15. Generemos ahora nuestra clase Bean que ser el transporte del objeto producto esto es.. ProductoTO.java 16. Generemos un nuevo archivo *.java

10

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

18. Inicialmente insertamos el cdigo: private String nombreProducto; private String descripcion; private String precio; 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 botn derecho del ratn 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.

11

23. Seleccionamos con el botn derecho del ratn sobre la estructura del descriptor y seleccionamos Form beans

24. Luego insertamos un form bean

25. Y escribimos sus propiedades.

12

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 mtodo validate:
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 descripcin del producto")); } return errores; }

29. Regresemos al diseo de struts config y arrastremos un Action y un Page. 30. Demos al Action el nombre guardarProducto y al Page desplegarProductoGuardado.jsp

13

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 accin guardarProducto tenga xito mostrar la pgina 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 cdigo:

14

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 import import import org.apache.struts.action.Action; org.apache.struts.action.ActionForm; org.apache.struts.action.ActionForward; 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"); } }

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 cdigo fuente que interacta con Java, las bibliotecas que lo contienen y la pgina JSP. Aadimos la biblioteca de marcas JSTL (Java Estndar Tag Libraries).

15

a. Seleccionamo las propiedades del proyecto:

b. Seleccionamos las bibliotecas JSTL Core 1.1

16

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

d. Arrastra a la derecha de Detalles un tag out y escribe sus propiedades:

rollo explicativo: $ indica instruccin por evaluar, { indica inicia la instruccin, producto.nombreProducto es claro, es el dato a obtener y } indica fin de la instruccin. Existen varias tags, te toca estudiarlas.. e. Haz lo mismo con los otros dos campos. f. Ahora.. a correr esta aplicacin g. Selecciona de rbol de aplicaciones la pgina JSP que contiene la forma para aadir productos clic con el derecho y ruuunnnnn. As se ve la pgina inicial.. llena los datos, observa que si no llenas los campos no se va a ningn lado.

17

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

18

Uso de biblioteca de marcas HTML y validacin especfica.


El tutorial anterior no est completo debido a que no hemos visto los mensajes de error en pantalla, adems los valores ya escritos no se conservan. Bien, modifiqumoslo para que tenga esas caractersticas. Para esto necesitamos usar las marcas de la biblioteca HTML, una de las tres bibliotecas que tiene struts. Comencemos 1. Generemos una aplicacin 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 automticamente las bibliotecas tag de struts. 3. Insertemos un Page Forward de la paleta de struts y seleccionemos la biblioteca struts HTML. 4. Aade la siguiente lnea a desplegarFormaParaAnadirProducto.jsp, justo debajo de la directiva page.
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>

5. Inserta la siguiente lnea despus de la marca <body> : <html:errors/> 6. Cambia la marca <input type=Text por 7. Haz lo mismo con las otras dos marcas Text. 8. La marca form cmbiala 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 11. Puedes crear desde cero esta pgina, 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
<html:reset/> <html:submit value="Aadir producto"/> <html:text property="nombreProducto"/>

19

a. Modifiquemos FormaProducto de modo que el mtodo validate que as:


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

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

Observa que hay una lnea de errores por cada error que necesites. No olvides agregar a la FormaProducto: b. Ahora a correr..
import org.apache.struts.action.ActionError;

20

Otro ejemplo, obtener producto y actualizar producto


Habamos visto que solo la segunda accin estaba asociada con una forma. Veremos como usar ahora dos acciones. obtener producto actualizar producto

La accin obtener producto obtiene un producto de la base de datos y lo despliega en una forma. Esta forma te permite la edicin de los valores. Al presionar el botn Actualizar se llamar a la accin actualizarProducto y veremos un mensaje que nos indica que el producto se ha actualizado. A continuacin se muestra el archivo struts-config.xml, sigue su esquema para crear tu aplicacin:
<?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>

21

Enseguida se muestra el contenido de obtenerProductoAction.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 import import import org.apache.struts.action.Action; org.apache.struts.action.ActionForm; org.apache.struts.action.ActionForward; 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 porttil 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");

} }

Aqu tenemos el cdigo de actualizarProductoAction.java

22

package actualizarProductos.action; import java.io.IOException; import actualizarProductos.forma.FormaProducto; import import import import import import import import actualizarProductos.to.ProductoTO; javax.servlet.ServletException; javax.servlet.http.HttpServletRequest; javax.servlet.http.HttpServletResponse; org.apache.struts.action.Action; org.apache.struts.action.ActionForm; org.apache.struts.action.ActionForward; org.apache.struts.action.ActionMapping;

public class ActualizarProductoAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, 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"); ServletException {

El contenido de la pgina JSP productoActualizado.jsp es:

23

<%@ page contentType="text/html;charset=windows-1252"%> <%@ a ensamblar todo y ejecutar. Ahora, taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <html> <head> Que tal. Simple? .. <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>

24

Asistentes

(Dicho de otra forma, formas multipgina.) Algunas veces, para hacer que una aplicacin sea ms amigable se puede dividir en varias formas pequeas. En este caso se tendr un action form que se mapea a mltiples formas HTML y se guarda en un objeto HttpSession (durante todo la vida de la sesin). Generemos otra aplicacin que se usar para almacenar informacin de empleados, se usarn 3 formas. La primera obtiene el puesto del empleado, la segunda el nombre del empleado y la tercera su direccin. Se har una llamada a una accin guardarEmpleado y se enivar una pgina de confirmacin. Aqu se muestra la estructura del directorio que contiene nuestra aplicacin en Jdeveloper. Paso a paso. 1. Generemos una aplicacin 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, llammosle 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, aade los campos que aadiste 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.

25