struts java en eclipse
DESCRIPTION
ejemplo basico en STRUTSTRANSCRIPT
TUTORIAL FRAMEWORKS STRUTS
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 2
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 3
INTRODUCCIÓN A STRUTS CON ECLIPSE .............................................................................................. 7
FORMULARIO LOGIN STRUTS ECLIPSE ................................................................................................ 14
EL FICHERO CSS ESTILO.CSS ES EL QUE SE VA A UTILIZAR PARA LA MAQUETACIÓN DEL EJEMPLO..................................... 17 CÓDIGO DEL FICHERO DE PROPIEDADES MESSAGERESOURCES_ES_ES .................................................................... 19 CÓDIGO DE LA CLASE JAVA “PARA EL ACTIONFORM” LA LLAMAMOS FORMULARIOFORM ........................................... 20 CÓDIGO JAVA DE LA CLASE “ACTION” LA LLAMAMOS ACCIONLOGIN ...................................................................... 22
FORMULARIO LOGIN STRUTS 2 PARTE ............................................................................................... 26
CÓDIGO FUENTE DE LA PÁGINA CACELADA.JSP ................................................................................................... 26 CÓDIGO FUENTE DE LA PÁGINA SATISFACTORIA.JSP ............................................................................................. 27 CONFIGURACIÓN DEL FICHERO STRUTS‐CONFING.XML ......................................................................................... 28 ESTE FRAGMENTO YA LO TENÍAMOS DEL HOLAMUNDO ........................................................................................ 28 FRAGMENTO CORRESPONDIENTE AL MAPEO DE LOS ACTION ................................................................................. 28
CREAR UNA VENTANA DE ERROR 404 Y 500 EN STRUTS CON ECLIPSE ................................................. 30
PARA EL ERROR 500 CLAVES PARA MESSAGERESOURCES.PROPERTIES .................................................................... 30 PARA LA PÁGINA 404.JSP .............................................................................................................................. 30 PARA LA PÁGINA 500.JSP .............................................................................................................................. 31 ERROR 500 EJEMPLO ................................................................................................................................... 31
FORMULARIO DYNAACTIONFORM STRUTS ECLIPSE ........................................................................... 32
VENTANA DE REGISTRO DINÁMICO .................................................................................................................. 32 VENTANA DE DATOSPERSONALES UNA VEZ EL REGISTRO HA SIDO ENVIADO .............................................................. 32 FICHERO FORMULARIODINAMICO.JSP PARA (PARA CREARLO VIENE EN POST DE LOGIN STRUTS ANTERIOR) ...................... 33 CLASE ACTION DENTRO DEL PACKAGE ACCIONES ACCIONDINAMICA.JAVA ................................................................ 34 VENTANA CANCELADA2 ................................................................................................................................ 35 PÁGINA JSP CANCELADA2.JSP ......................................................................................................................... 35 PÁGINA DATOSPERSONALES.JSP ...................................................................................................................... 36
STRUTS FORMULARIO DYNAVALIDATORFORM ECLIPSE ..................................................................... 40
CÓDIGO DE LA PÁGINA EJERCICIOS.JSP ............................................................................................................. 41 CÓDIGO DE LA PÁGINA FORMDINAVALIDACION.JSP ............................................................................................. 43 IMAGEN DEL FORMULARIO ............................................................................................................................. 44 CÓDIGO FUENTE DE LA PÁGINA PERSONALES DATOSPERSONALES2.JSP .................................................................... 45 COFIGURACIÓN DEL ACTION EN EL FICHERO STRUTS‐CONFIG.XML .......................................................................... 46 CLASE ACTION EN EL PACKAGE DE ACCIONES ..................................................................................................... 47 CÓDIGO DE MESSAGERESOURCES_ES_ES.PROPERTIES ........................................................................................ 47
STRUTS DISPATCHACTION ECLIPSE .................................................................................................... 49
CÓDIGO PARA LA CONFIGURACIÓN DEL ARCHIVO STRUTS‐CONFIG.XML ................................................................... 49 CÓDIGO QUE AÑADIMOS AL ARCHIVO EJERCICIOS.JSP .......................................................................................... 49 DECLARACIÓN DEL FORMULARIO DINÁMICO EN EL FICHERO STRUTS‐CONFIG.XML ..................................................... 50 CONFIGURACIÓN DEL ACTION EN EL STRUTS‐CONFIG.XML ACTION “DINAMICOLIBRO2″ .............................................. 50 CÓDIGO FUENTE DEL FICHERO DEL FICHERO FORMULARIODISPATCH.JSP .................................................................. 56 CÓDIGO FUENTE DEL FICHERO EDICION.JSP ....................................................................................................... 57 CÓDIGO FUENTE DEL FICHERO DATOSLIBROS.JSP ................................................................................................ 58
IBATIS PROYECTO WEB ECLIPSE ......................................................................................................... 59
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 4
CLASE BEAN LIBRO.JAVA ............................................................................................................................... 59 FICHERO DE CONFIGURACIÓN DE SQL MAP ....................................................................................................... 61
STRUTS TILES PROYECTO WEB ECLIPSE .............................................................................................. 66
STRUTS TILES PROYECTO WEB ECLIPSE 2 PARTE ................................................................................. 71
TUTORIAL HTML STRUTS TAGS .......................................................................................................... 74
TUTORIAL DE LOOKUPDISPATCHACTION STRUTS ............................................................................... 75
CÓDIGO DE PÁGINA EJERCICIOS.JSP COMO LOS ANTERIORES EJEMPLOS .................................................................... 75 CONFIGURACION DEL BEAN DYNAVALIDATORFORM ........................................................................................... 76 CONFIGURACIÓN DEL ARCHIVO STRUTS‐CONFIG.XML PARA ACTION MAPPING ......................................................... 76 CONFIGURACIÓN DEL FICHERO DE PROPIEDADES PROPERTIES ................................................................................ 77 CÓDIGO DE LA PÁGINA JSP FORMULARIOLOOKUP.JSP .......................................................................................... 77 CLASE LOOKUPDISPATCHACTION ACCIONLOOKUPDISPATCHACTION.JAVA .............................................................. 78
DATASOURCE STRUTS 1.2.X PROYECTO WEB ECLIPSE......................................................................... 83
DATASOURCE STRUTS ................................................................................................................................... 83 CONFIGURACIÓN DEL ARCHIVO STRUTS‐CONFIG.XML PARA EL DATASOURCE ............................................................ 83 CONFIGURACIÓN DE LOS ACTIONS PARA EL STRUTS‐CONFIG.XML............................................................................ 84 CÓDIGO DE LA PÁGINA FALLIDA.JSP ................................................................................................................. 85 CÓDIGO DE LA PÁGINA REGISTRO SATISFACTORIO ............................................................................................... 86 CÓDIGO DE LA CLASE JAVA ACCIONBASEDATOS DENTRO DEL PACKAGE DE ACCIONES ................................................. 87
DATASOURCE STRUTS 1.3.X PROYECTO WEB ECLIPSE......................................................................... 90
CONFIGURACIÓN DE LA ACCIÓN DATASOURCE.DO EN EL STRUTS‐CONFIG.XML .......................................................... 90 CONFIGURACIÓN DEL FICHERO DE PROPIEDADES ................................................................................................ 90 CLASE CONEXION DENTRO DEL PACKAGE CONEXIONES ........................................................................................ 92 CONFIGURACIÓN DEL FICHERO WEB.XML .......................................................................................................... 93 FICHERO CONTEXT.XML ................................................................................................................................. 93 CONFIGURACIÓN DE LA ACCIÓN FORMULARIODATASOURCE.DO ............................................................................. 94 FORMULARIODATASOURCE.JSP ....................................................................................................................... 96 MOSTRARLISTADO.JSP................................................................................................................................... 97
MOSTRANDO LISTADO DE DATOS.................................................................................................... 100
DESARROLLO WEB UPLOADFILE STRUTS .......................................................................................... 102
CÓDIGO DE LA CLASE SUBIR ARCHIVO ............................................................................................................. 103 CÓDIGO DE LA PÁGINA JSP ENCARGADA DE MOSTRAR EL FORMULARIO DE SUBIDA DE ARCHIVO .................................. 104 EN EL FICHERO DE PROPIEDADES ................................................................................................................... 105 CLASE BEAN PARA EL FORMULARIO ................................................................................................................ 105
DESARROLLO WEB MÚLTIPLES ARCHIVOS DE CONFIGURACIÓN STRUTS ........................................... 108
CÓDIGO DE LA PÁGINA ENLACEPRIVADO ......................................................................................................... 108 EN EL FICHERO WEB.XML DEL PROYECTO ........................................................................................................ 110
DESARROLLO WEB COMODINES STRUTS .......................................................................................... 111
CONFIGURACIÓN DEL ARCHIVO STRUTS‐CONFIGWILDCARD.XML ......................................................................... 111 CÓDIGO DE ENLACES.JSP .............................................................................................................................. 112 PÁGINA 1 JSP ............................................................................................................................................ 112 PÁGINA 2 JSP ............................................................................................................................................ 113
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 5
CREACIÓN DE UN PLUGIN CON STRUTS XML DOM ........................................................................... 114
CLASE OBRERO .......................................................................................................................................... 117 CONFIGURACIÓN DEL ACTION EN STRUTS‐CONFIG.XML ...................................................................................... 118
INTEGRACIÓN STRUTS HIBERNATE .................................................................................................. 119
ARCHIVO DE CONFIGURACIÓN HIBERNATE.CFG,XML .......................................................................................... 125
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 6
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 7
INTRODUCCIÓN A STRUTS CON ECLIPSE
Vamos a descargarnos el proyecto struts de la página web oficial
http://struts.apache.org/download.cgi
escogemos la versión 1.3.10
La ubicamos en nuestro sistema de archivos independientemente del sistema operativo que utilicemos y descomprimimos el fichero zip
Dentro del la carpeta del proyecto de struts hay un fichero .war que contiene la estructura de una aplicación en blanco. Se utiliza para no tener que ir incorporando jar al proyecto ni tlds para las etiquetas struts.
la ruta es carpeta struts proyecto que para la versión que hemos descargado es path vuestro\struts‐1.3.10\apps\struts‐blank‐1.3.10.war
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 8
Lo único que tenemos que hacer es abrir nuestro eclipse e importar dicho proyecto en blanco y darle un nombre nuevo para poder empezar.
File, import war y seleccionar la ruta donde esta nuestro fichero blank.war para la version 1.3.10
le damos a next y nos aparece otro nuevo cuadro de diálogo donde le damos nombre al proyecto y le decimos donde esta el fichero blank.war
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 9
pulsamos sobre el botón “finish” y en la pestaña explorador del proyecto vemos la estructura de directorios del nuevo proyecto en blanco “holamundo”
Al igual que en los proyectos de jee para ejecutar el proyecto vamos a “run as run on server escogemos tomcat” “y sale la pantalla de bienvenida del proyecto struts
Vamos a modificar el proyecto para que salga un mensaje en castellano, para ello vamos a conservar las jsp que tiene el proyecto por defecto y crearemos un nuevo fichero de propiedades llamado MesssageResources_es_ES.properties en el que vamos a incluir una claves para que
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 10
salga por pantalla un mensaje de bienvenida.
En el nuevo fichero de properties
1
2
3
welcome.title=Holamundo Struts
welcome.heading=Bienvenida!
welcome.message=Holamundo Struts
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 11
Y dentro del fichero de configuración struts‐config.xml ponemos lo siguiente
1
2
3
4
<!‐‐ ======================================== Message Resources Definitions ‐‐>
<message‐resources parameter="MessageResources_es_ES" />
<message‐resources parameter="MessageResources"/>
Vamos a entender un poco esto que acabamos de hacer y así entender el funcionamiento de struts. Dentro del directorio WebCotent que es como en jee el directorio público hay una carpeta pages donde tenemos una página welcome.jsp con este contenido
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<%@ taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags‐html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags‐logic" prefix="logic" %>
<html:html>
<head>
<title><bean:message key="welcome.title"/></title>
<html:base/>
</head>
<body bgcolor="white">
<logic:notPresent name="org.apache.struts.action.MESSAGE" scope="application">
<font color="red">
ERROR: Application resources not loaded ‐‐ check servlet container
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 12
15
16
17
18
19
20
21
22
23
logs for error messages.
</font>
</logic:notPresent>
<h3><bean:message key="welcome.heading"/></h3>
<p><bean:message key="welcome.message"/></p>
</body>
</html:html>
Vamos a centrarnos solamente en porque sale el mensaje en castellano, decir a modo de comentario que struts tiene sus propios tags html van precedidios de htm: se pueden ver varios casos como y después otras etiquetas.
vemos que la etiqueta bean:message tiene un atributo key con un valor welcome.title para el caso del título, lo mismo va a suceder con el encabezado y con mensaje. Lo que hace esta etiqueta es obtener el valor del fichero de configuración recien creado
el formato de este fichero de de propiedades es clave=valor
Si nos fijamos en navegador y vemos la url del proyecto arrancado en local, observamos que termina en Welcome.do, nos esta indicando que struts está realizando la acción Welcome.
1
2
3
4
5
6
7
8
9
<!‐‐ =========================================== Global Forward Definitions ‐‐>
<global‐forwards>
<!‐‐ Default forward to "Welcome" action ‐‐>
<!‐‐ Demonstrates using index.jsp to forward ‐‐>
<forward
name="welcome"
path="/Welcome.do"/>
</global‐forwards>
Que se mapea en la seccion de acction metiante
1 <!‐‐ =========================================== Action Mapping Definitions ‐‐>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 13
2
3
4
5
6
7
8
<action‐mappings>
<!‐‐ Default "Welcome" action ‐‐>
<!‐‐ Forwards to Welcome.jsp ‐‐>
<action
path="/Welcome"
forward="/pages/Welcome.jsp"/>
La accion Welcome.do esta mapeada en la seccion action mapping mediante el nombre de path igual que la accion pero sin do path=”/Welcome” y se reenvía la la página jsp que viene con el proyecto struts “/pages/Welcome.jp” dentro del directoria público WebContent
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 14
FORMULARIO LOGIN STRUTS ECLIPSE
Para hacer este tutorial vamos a partir del proyecto web Holamundo realizado anteriormente Holamundo
En este ejemplo se ven con eclipse la utilización de los Action y los ActionForm así como la configuración del struts‐ confing, utilización y carga de imágenes y utilización de archivos css en proyectos struts.
No hay conexión para base de datos se deja para otros post y no se utiliza el DynaActionForm que los veremos en otros post.
Se presenta el interfaz gráfico de la apliación para un mejor entendimiento, tenemos un formulario de registro que toma el nombre el apellido y otros dos campos clave y confirmación de clave, todos estos campos deben ser rellenados por el usuario y se comprueba que la clave y su confirmación son iguales. El usuario tiene la posibilidad de cancelar el registro y vover a la pagina de registro desde la de cancelación.
Ventana de registro
creación de la página login.jsp con eclipse las demás páginas se realizarán de la misma forma (“cambiamos el nombre del la página)
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 15
código correspondiente al fichero login.jsp es el código asociado a la “ventana de registro”
Una de las características de struts es que tiene su propios tags para html, vienen siempre con la palabra html: y despues el nombre de la etiqueta en cuestion.
Para la categoría de j2ee de este sitio web ya hicieron ejemplos de integración de css con j2ee, comento esto porque hay una diferencia importante con struts. Para mucha gente que viene de otros lenguajes o de hacer jsp estaran acostumbrados a colocar el archivo css en un determinado directorio y enlazarlo mediante la etiquela “link”. Bien para que las css o las imágenes las podamos incluir en un proyecto struts es necesario incluir en el head de la página jsp de struts la etiqueta .
Si nos fijamos en las jsp vemos que aparecen en todas ellas, lo que hace esta etiqueta es establecer el punto de referencia de la página con respecto al resto al resto de recursos del proyecto.
Ejemplo, si yo soy la página login.jsp y me dicen que hay una css en “../css/estilo.css” entonces se que tengo que buscar en mi directorio padre y bajar al directorio css y alli encuentro estilo.css. Si no tengo la referencia base no puedo encontrar los recursos css ni de imagen.
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 16
Además en la cabecera de la jsp debemos de incluir el <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%><%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title> <bean:message key="titulo.login"/></title> <html:base/> <link rel="stylesheet" type="text/css" href="../css/estilo.css" /> </head> <body> <div id="contenedor"> <h2> <bean:message key="titulo.login"/> </h2> <div id="errores"> <html:errors/> </div> <div id="imagen"> <html:img srcKey="login.imagen" titleKey="login.imagen.alt"/> </div> <div id="contenido"> <html:form action="loginAction" focus="nombre" styleId="formulario" method="post"> <div class="campo"> <bean:message key="login.nombre"/> <html:text property="nombre"/> </div> <div class="campo"> <bean:message key="login.apellidos"/> <html:text property="apellidos"/> </div> <div class="campo"> <bean:message key="login.clave" /> <html:password property="clave" maxlength="8" size="8"/> </div> <div class="campo"> <bean:message key="login.claveConfirmacion" /> <html:password property="claveConfirmacion" maxlength="8" size="8"/> </div> <html:submit styleClass="boton" value="enviar"/> <html:cancel styleClass="boton" value="cancelar"/>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 17
54 55 56 57 58 59 60 61 62 63 64
</html:form> </div> <div id="pie"> <p> www.railsymas.com </p> </div> </div> </body> </html:html>
Se crean dos carpetas nuevas al proyecto llamadas imagenes y css (“cada uno las puede llamar como quiera mientras mantenga la correspondencia con otras partes del proyecto”)
Imagen de creación, carpeta imagenes
EL FICHERO CSS ESTILO.CSS ES EL QUE SE VA A UTILIZAR PARA LA MAQUETACIÓN DEL EJEMPLO
1 2 3
#contenedor { width:600px; margin‐left:auto;
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 18
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
margin‐right:auto; } .campo { margin‐top:10px; } #imagen { float:right; } .boton { margin: 10px 5px; background‐color:#554444; color:#fff; width:100px; } #formulario { margin‐top:60px; font‐size:16px; } #errores { background‐color:#e6dfd5; color:#424c56; } #errores ul li { list‐style‐image:url("../imagenes/flechaderecha.png"); } #errores ul { border‐color:#f00; } h2 { text‐align:center; } #pie { clear:both; height:30px; background‐color:#424c56; } #pie p { text‐align:right; font‐size:14px; background‐color:#e6dfd5; }
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 19
CÓDIGO DEL FICHERO DE PROPIEDADES MESSAGERESOURCES_ES_ES
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
#claves para login titulo.login=Registro usuario login.nombre = nombre login.apellidos = apellidos login.claveConfirmacion=confirmación de password login.clave=password login.imagen.alt= icono usuario login.imagen = ../imagenes/usuario.png; #claves de error error.login.nombre = falta el campo nombre error.login.apellidos = falta el campo apellidos error.login.clave = falta el campo clave error.login.claveConfirmacion = falta el campo claveconfirmacionerror.login2 = repite la clave #claves para satisfactoria satisfactoria.titulo = Resgistro correcto satisfactoria.imagen = ../imagenes/correcto.png satisfactoria.imagen.alt = imagen correcto satisfactoria.mensaje = Te has registrado correctamente #claves para cancelada cancelada.titulo = Registro cancelado cancelada.mensaje = No te has registrado en el sistema cancelada.imagen.alt = imagen cancelado cancelada.imagen = ../imagenes/cancelado.png cancelada.login = Cancelación #claves para welcome welcome.title=Holamundo Struts welcome.heading=Bienvenida! welcome.message=Holamundo Struts
Creamos la nueva clase FormularioFrom dentro del package formularios
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 20
CÓDIGO DE LA CLASE JAVA “PARA EL ACTIONFORM” LA LLAMAMOS FORMULARIOFORM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
package formularios; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionMessage; import javax.servlet.http.HttpServletRequest; public class FormularioForm extends ActionForm { static final long serialVersionUID = 1L; private String nombre; private String apellidos; private String clave; private String claveConfirmacion; //métodos getters y setters del formulario public String getNombre() { return nombre; }
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 21
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
public void setNombre(String nombre) { this.nombre = nombre; } public String getApellidos() { return apellidos; } public void setApellidos(String apellidos) { this.apellidos = apellidos; } public String getClave() { return clave; } public void setClave(String clave) { this.clave = clave; } public String getClaveConfirmacion() { return claveConfirmacion; } public void setClaveConfirmacion(String claveConfirmacion) { this.claveConfirmacion = claveConfirmacion; } //método que permite la validación de los campos del formulario public ActionErrors validate ( ActionMapping mapping, HttpServletRequest request ) { //creamos un nuevo objeto ActionErrors ActionErrors errores = new ActionErrors(); if ( nombre == null ||nombre.length() == 0) { errores.add("nombre", new ActionMessage("error.login.nombre")); } if ( apellidos == null ||apellidos.length() == 0 ) { errores.add("apellidos", new ActionMessage("error.login.apellidos")); } if ( clave ==null || clave.length() == 0) { errores.add("clave", new ActionMessage("error.login.clave")); } if ( claveConfirmacion == null ||claveConfirmacion.length() == 0 ) { errores.add("claveConfirmacion", new ActionMessage("error.login.claveConfirmacion")); } if ( !clave.equals(claveConfirmacion) ) { errores.add("confirmacion", new ActionMessage("error.login2")); }
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 22
82 83 84 85 86 87 88 89 90 91 92 93 94
return errores; } //método para resetear los campos del formulario public void reset () { this.nombre = null; this.apellidos = null; this.claveConfirmacion = null; this.clave = null; } }
Cremos una nueva clase Action dentro del package Acciones
CÓDIGO JAVA DE LA CLASE “ACTION” LA LLAMAMOS ACCIONLOGIN
1 2 3 4 5 6 7 8
package acciones; import org.apache.struts.action.Action; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionForward;
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 23
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
import formularios.*; //clase action public class AccionLogin extends Action { private String resultado; // creación del método execute public ActionForward execute ( ActionMapping mapping, ActionForm form ,HttpServletRequest request, HttpServletResponse response ) throws Exception { //si el usuario pulsa el botón de cancelado if ( this.isCancelled(request) ) { //como tenemos en el método execute el objeto ActionMapging podemos mandar a un reenvio del struts‐config return mapping.findForward("cancelada"); } else { //creamos un objeto formularioForm FormularioForm formularioform = (FormularioForm) form; return mapping.findForward("satisfactoria"); } } }
Si intentamos ejecutar una clase Action sin su correspondiente ActionForm nos da el siguiente error al ejecutar el proyeto (“sale mucho más por pantalla pero son las dos líneas claves”)
1 2 3
javax.servlet.ServletException: Form bean not specified on mapping for action: "loginAction" org.apache.jasper.JasperException: Exception in JSP: /pages/login.jsp
Ventana de errores campos vacíos
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 24
Error de clave (“no son iguales”)
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 25
En la segunda parte de este ejemplo formulario login struts 2 parte eclipse
Se ven las páginas cancelada.jsp y satisfactoria.jsp así como la cofiguración del struts‐config.xml y explicaciones correspondientes.
Agradecimientos por las imágenes utilizadas a vía www.webintenta.com
http://www.smashingmagazine.com/2008/08/27/on‐stage‐a‐free‐icon‐set/
http://nick7even.deviantart.com/gallery/
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 26
FORMULARIO LOGIN STRUTS 2 PARTE
Ventana de cancelación
Enlace a la primera parte del tutorial login struts
CÓDIGO FUENTE DE LA PÁGINA CACELADA.JSP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%> <%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title> <bean:message key="cancelada.titulo"/></title> <html:base/> <link rel="stylesheet" type="text/css" href="../css/estilo.css" /> </head> <body> <div id="contenedor"> <h2> <bean:message key="cancelada.login"/> </h2> <div id="imagen"> <html:img srcKey="cancelada.imagen" titleKey="cancelada.imagen.alt"/> </div>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 27
24 25 26 27 28 29 30 31 32 33 34 35 36 37
<div id="mensaje"> <bean:message key="cancelada.mensaje"/> <div class="campo"> <html:link page="/pages/login.jsp" > Volver al formulario login </html:link> </div> </div> <div id="pie"> <p> www.railsymas.com </p> </div> </div> </body> </html:html>
Ventana Correcto cuando el usuario tiene todos los campos correctos
CÓDIGO FUENTE DE LA PÁGINA SATISFACTORIA.JSP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%><%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title> <bean:message key="satisfactoria.titulo"/></title> <html:base/> <link rel="stylesheet" type="text/css" href="../css/estilo.css" /> </head> <body> <div id="contenedor"> <h2> <bean:message key="satisfactoria.titulo"/> </h2> <div id="imagen">
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 28
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
<html:img srcKey="satisfactoria.imagen" titleKey="satisfactoria.imagen.alt"/> </div> <div id="mensaje"> <bean:message key="satisfactoria.mensaje"/> <div class="campo"> <bean:write name="loginFormulario" property="nombre"/> </div> </div> <div id="pie"> <p> www.railsymas.com </p> </div> </div> </body> </html:html>
CONFIGURACIÓN DEL FICHERO STRUTS‐CONFING.XML
1 2 3 4 5 6 7 8 9
<!‐‐ ================================================ Form Bean Definitions ‐‐> <form‐beans> <form‐bean name="loginFormulario" type="formularios.FormularioForm"/> </form‐beans>
ESTE FRAGMENTO YA LO TENÍAMOS DEL HOLAMUNDO
1 2 3 4 5 6 7 8 9
<!‐‐ =========================================== Global Forward Definitions ‐‐> <global‐forwards> <!‐‐ Default forward to "Welcome" action ‐‐> <!‐‐ Demonstrates using index.jsp to forward ‐‐> <forward name="welcome" path="/Welcome.do"/> </global‐forwards>
FRAGMENTO CORRESPONDIENTE AL MAPEO DE LOS ACTION
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<!‐‐ =========================================== Action Mapping Definitions ‐‐> <action‐mappings> <!‐‐ Default "Welcome" action ‐‐> <!‐‐ Forwards to Welcome.jsp ‐‐> <!‐‐ modificamos el forward para que apunte a la pagina de login.jsp ‐‐> <action path="/Welcome" forward="/pages/login.jsp"/> <!‐‐ creamos la accion login ‐‐> <action path="/loginAction"
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 29
15 16 17 18 19 20 21 22 23 24 25
type="acciones.AccionLogin" scope="session" name="loginFormulario" validate="true" input="/pages/login.jsp" > <set‐property property="cancellable" value="true" /> <exception key="errors.cancel" type="org.apache.struts.action.InvalidCancelException" path="/Welcome.do"/> <forward name="cancelada" path="/pages/cancelada.jsp" /> <forward name="satisfactoria" path="/pages/satisfactoria.jsp"/> </action>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 30
CREAR UNA VENTANA DE ERROR 404 Y 500 EN STRUTS CON ECLIPSE
Cuando se produce un error 404, muchas veces cuando navegamos por internet nos podemos encontrar con este error. La visualización del mismo depende del navegador que estemos utilizando o bien de la gestión de dicho error por parte del sito web al que queremos acceder.
En struts también podemos gestionar dichos errores, para ello nos vamos al fichero de descriptor de despliegue web.xml y escribimos lo siguiente
1 2 3 4 5 6
<!‐‐ declaramos la página de error ‐‐> <error‐page> <error‐code>404</error‐code> <location>/pages/404.jsp</location> </error‐page>
1 2 3 4
<error‐page> <error‐code>500</error‐code> <location>/pages/500.jsp</location> </error‐page>
Las situaciones en las que se produce este error serian cuando nos brindan un enlace a un sitio y el recurso al que apunta el enlace no existe o bien cuando escribimos directamente una dirección de una página sobre un sitio web y lo hacemos mal.
PARA EL ERROR 500 CLAVES PARA MESSAGERESOURCES.PROPERTIES
1 2 3 4 5 6 7 8 9 10 11
# error 404 error.404.titulo = Recurso no disponible error.404.imagen = ../imagenes/cancelado.png error.404.imagen.alt = no disponible error.404.mensaje = página no encontrada # error 500 error.500.titulo = Error en la p´gina error.500.imagen = ../imagenes/cancelado.png error.500.imagen.alt = no disponible error.500.mensaje = Lo sentimos, se ha producido un error interno
PARA LA PÁGINA 404.JSP
1 2 3 4 5 6 7 8 9 10 11
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%><%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title><bean:message key="error.404.titulo"/></title>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 31
12 13 14 15 16 17 18 19 20 21
<html:base/> </head> <body> <div style="float:left; margin‐left:200px"> <h1> <bean:message key="error.404.mensaje"/> </h1> </div> <html:img srcKey="error.404.imagen" titleKey="error.404.imagen.alt"/> </body> </html:html>
PARA LA PÁGINA 500.JSP
Exactamente igual
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%><%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title><bean:message key="error.500.titulo"/></title> <html:base/> </head> <body> <div style="float:left; margin‐left:200px"> <h1> <bean:message key="error.500.mensaje"/> </h1> </div> <html:img srcKey="error.500.imagen" titleKey="error.500.imagen.alt"/> </body> </html:html>
ERROR 500 EJEMPLO
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 32
FORMULARIO DYNAACTIONFORM STRUTS ECLIPSE
Para este tutorial partimos del proyecto holamundo creado inicialmente en anteriores posts, esta imagen se corresponde a la ventana de login para el formulario dinámico
VENTANA DE REGISTRO DINÁMICO
VENTANA DE DATOSPERSONALES UNA VEZ EL REGISTRO HA SIDO ENVIADO
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 33
Lo primero de todo que es DynaActionForm o mejor ¿para que sirve?, bueno esta clase permite a struts trabajar con los campos de un formulario sin tener que hacer una clase FormBean como en el ejemplo de login struts anteriormente visto.
Pasos que hay que seguir o que es lo que necesitamos, 1 formulario jsp , 2 una configuración en el archivo struts‐config.xml y 3 una clase DynaActionForm.java
1 El formulario es como siempre una página web con las etiquetas struts 2 La configuración del archivo struts‐config.xml consta de dos pasos 2.1 La configuración del Bean dinámico aqui se indica las propiedades que va a tener este nuevo bean 2.2 La configuación del la clase Action responsable de tratar el formulario Se establece la relación con el bean dynaActionForm y la clase que trata los campos del formulariio y los reenvios a las páginas jsp segun se hayan introducido los datos bien o no.
FICHERO FORMULARIODINAMICO.JSP PARA (PARA CREARLO VIENE EN POST DE LOGIN STRUTS ANTERIOR)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%><!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <html:html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title><bean:message key="titulo.dinamico"/></title> <html:base/> <link rel="stylesheet" type="text/css" href="../css/estilo.css" /> </head> <body> <div id="contenedor"> <h2><bean:message key="titulo.dinamico"/></h2> <div id="errores"> <html:errors/> </div> <div id="imagen"> <html:img srcKey="dinamico.registro.imagen" titleKey="dinamico.registro.imagen.alt"/> </div> <div id="contenido"> <html:form action="dinamicoAction" focus="nombre" styleId="formulario" method="post"> <div class="campo"> <bean:message key="login.nombre"/> <html:text property="nombre"/> </div> <div class="campo"> <bean:message key="login.domicilio"/> <html:text property="domicilio"/> </div>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 34
35 36 37 38 39 40 41 42 43 44 45 46 47 48
<div class="campo"> <bean:message key="login.edad" /> <html:password property="edad" maxlength="3" size="3"/> </div> <html:submit styleClass="boton" value="enviar"/> <html:cancel styleClass="boton" value="cancelar"/> </html:form> </div> <div id="pie"> <p> www.railsymas.com </p> </div> </div> </body> </html:html>
CLASE ACTION DENTRO DEL PACKAGE ACCIONES ACCIONDINAMICA.JAVA
Si los campos están vacíos se mapea la hacía cancelada y si están completos hacia la
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
package acciones; import org.apache.struts.action.Action; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionForm; import org.apache.struts.action.DynaActionForm; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionMessage; public class AccionDinamica extends Action { public ActionForward execute ( ActionMapping mapping, ActionForm form ,HttpServletRequest request , HttpServletResponse response ) throws Exception { //creamos un objeto dynamicactionform DynaActionForm formularioDinamico = (DynaActionForm) form; ActionForward reenvio = null; ActionErrors mensajes = new ActionErrors(); if (((String) formularioDinamico.get("nombre")).equals("") ) { mensajes.add("nombre",new ActionMessage("error.login.nombre")); } if (((String) formularioDinamico.get("domicilio")).equals("") ) {
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 35
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
mensajes.add("domicio",newActionMessage("error.login.domicilio")); } //preguntamos si hay errores para hacer el reenvio a la pagina if (mensajes.isEmpty()) { reenvio = mapping.findForward("datospersonales"); } else { reenvio = mapping.findForward("cancelada"); } System.out.print(reenvio.getPath()); return reenvio; } }
VENTANA CANCELADA2
PÁGINA JSP CANCELADA2.JSP
Página que muestra el mensaje de que la acción ha sido cancelada
1 <%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 36
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
<%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %><%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title> <bean:message key="cancelada.titulo"/></title> <html:base/> <link rel="stylesheet" type="text/css" href="../css/estilo.css" /> </head> <body> <div id="contenedor"> <h2> <bean:message key="cancelada.login"/> </h2> <div id="imagen"> <html:img srcKey="cancelada.imagen" titleKey="cancelada.imagen.alt"/> </div> <div id="mensaje"> <bean:message key="cancelada.mensaje"/> <div class="campo"> <html:link page="/pages/login.jsp" > Volver al formulario login </html:link> </div> </div> <div id="pie"> <p> www.railsymas.com </p> </div> </div> </body> </html:html>
PÁGINA DATOSPERSONALES.JSP
Esta página recupera los datos introducidos por el usuario mediante la etiqueta
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%><%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title><bean:message key="titulo.dinamico"/></title> <html:base/> <link rel="stylesheet" type="text/css" href="../css/estilo.css" /> </head> <body> <div id="contenedor">
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 37
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
<h2>Bienvenido <bean:write name="dinamicoFormulario" property="nombre"/></h2> <div id="imagen"> <html:img srcKey="dinamico.imagen" titleKey="dinamico.imagen.alt"/> </div> <div id="mensaje"> <bean:message key="dinamico.mensaje"/> <div class="campo"> <bean:write name="dinamicoFormulario" property="nombre"/> </div> <div class="campo"> <bean:write name="dinamicoFormulario" property="domicilio"/> </div> <div class="campo"> <bean:write name="dinamicoFormulario" property="edad"/> </div> </div> <div id="pie"> www.railsymas.com </div> </div> </body> </html:html>
Declaración del formulario dinámico en el fichero de configuración struts‐config.xml
En la definición del form bean vemos como a diferencia del ejemplo del login cuando teníamos un form bean y hacíamos una referencia mediante el atributo “type” a una clase de nuestro proyecto ahora lo hacemos a una clase de struts “org.apache.struts.action.DynaActionForm”. Después declaramos las propiedades del bean mediante su tipo y si queremos un valor inicial se pone el atributo “initial” con un valor
En el ejemplo se dan los valor a los campos nombre = usuarioPepe domicilio = domicilioPepe y se deja sin tocar la edad pero como estaba inicializada a 18 sale por pantalla. Además en la clase action no se mira si esta vacía o no ya que por defecto tiene el valor 18
1 2 3 4 5 6 7 8
<!‐‐ ================================================ Form Bean Definitions ‐‐> <form‐bean name="dinamicoFormulario" type="org.apache.struts.action.DynaActionForm" > <form‐property name="nombre" type="java.lang.String"/> <form‐property name="domicilio" type="java.lang.String"/> <form‐property name="edad" type="java.lang.Integer" initial="18"/> </form‐bean>
Declaración del reenvío global
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 38
Como funciona la aplicación bien hay un index.jsp por defecto en el proyecto esto ya viene asi configurado en el archivo web.xml, “fichero de despliegue”. Se genera entonces la acción Welcome.do en el reenvío global,
1 2 3 4 5 6 7 8 9
<!‐‐ =========================================== Global Forward Definitions ‐‐> <global‐forwards> <!‐‐ Default forward to "Welcome" action ‐‐> <!‐‐ Demonstrates using index.jsp to forward ‐‐> <forward name="welcome" path="/Welcome.do"/> </global‐forwards>
En las definiciones de las acciones en Action Mapping, la acción welcome recogido por el atributo path es mapeada al archivo jsp “formularioDinámico.jsp” por lo que es la primera página que sale por defecto.
Cuando el usuario rellena los campos y pulsa sobre los botones del formulario se procesa la accion “dinamicoAction” que se establece en el fichero struts‐config.xml por el atributo path y se mapea en el proyecto por la clase java “acciones.AccionDinámica”.
Se suele poner un package siempre para las clases acciones y otro para las clases bean “pero es gusto del consumidor hacerlo o no”
Cuando la clase AccionDinámica procesa los campos del formulario manda mediante un objeto de la clase actionMapping encontrar la referencia de un objeto mapeado en el struts‐config.xml mediante si estan bien los datos se mada a la pagina datospersonales,jsp por que en la clase AccionDinámima teníamos reenvio = mapping.findForward(“datospersonales”); y mediante el name=”datospersonales obtenimos la página datospersonales.jsp.
De la misma forma si los campos estan vacíos tenemos errores y mensajes.isEmpty() nos devuelve false por lo que nos manda a la página cancelada2.jsp
Una diferencia de este ejemplo con el del formulario de login, a parte de que nos evitamos una clase formbean es que no nos salen los errores en el formulario de recogida de datos, podríamos resolverlo con objetos de la clase AcctionMessages pero existe otra variante del DynaActionForm que si permite de una forma sencilla la validación de los campos llamada DynaActionFormValidator y lo veremos en otro posts.
1 2 3 4 5 6 7
<!‐‐ =========================================== Action Mapping Definitions ‐‐> <action‐mappings> <!‐‐ Default "Welcome" action ‐‐> <!‐‐ Forwards to Welcome.jsp ‐‐> <!‐‐ modificamos el forward para que apunte a la pagina de login.jsp ‐‐> <action
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 39
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
path="/Welcome" forward="/pages/formulariodinamico.jsp"/> <action path="/dinamicoAction" type="acciones.AccionDinamica" scope="request" name="dinamicoFormulario" input="/pages/formulariodinamico.jsp"> <set‐property property="cancellable" value="true" /> <forward name="cancelada" path="/pages/cancelada2.jsp" /> <forward name="datospersonales" path="/pages/datospersonales.jsp" /> </action>
claves para el archivo de propropiedades .properties como siempre el formato es clave=valor
1 2 3 4 5 6 7 8
#claves para dinamico dinamico.mensaje = Te has registrado correctamentedinamico.imagen = ../imagenes/base.jpg dinamico.imagen.alt = imagen icono registro dinamico.registro.imagen = ../imagenes/usuario2.pngdinamico.registro.imagen.alt = icono usuario titulo.dinamico = Registro dinámico
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 40
STRUTS FORMULARIO DYNAVALIDATORFORM ECLIPSE
En el anterior post para la categoría de struts habíamos visto los formularios dinámicos de struts, como repaso decíamos que eliminaban la creación de de la clase de tipo actionForm mediante la configuración del form bean en el fichero struts‐config.xml.
Lo que ocurria con la clase DynaActionForm era que aunque teníamos el código para la validación de los campos en la clase no funcionaba pero que se podían imprimir los mensajes y devolverlos mediante el objeto request de petición.
La validación también sería posible mediante javascript como otros lenguajes pero struts dispone de una clase que facilita todo esto, esta clase se llama DynaValidatorForm y permite la validación de los campos de un formulario dinámico.
En los ejemplos anteriores redirigíamos la accion Welcome.do a las páginas correspondientes de cada ejemplo con lo cual perdíamos en el proyecto la posibilidad de interactuar con los anteriores ejemplos, para que no ocurra eso se puede crear una página sólo de enlaces, a los diferentes ejercicios a modo de menú.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
<global‐forwards> <!‐‐ Default forward to "Welcome" action ‐‐> <!‐‐ Demonstrates using index.jsp to forward ‐‐> <forward name="welcome" path="/Welcome.do"/> </global‐forwards> <!‐‐ =========================================== Action Mapping Definitions ‐‐> <action‐mappings> <!‐‐ Default "Welcome" action ‐‐> <!‐‐ Forwards to Welcome.jsp ‐‐> <!‐‐ modificamos el forward para que apunte a la pagina de login.jsp ‐‐> <action path="/Welcome" forward="/pages/ejercicios.jsp"/>
lo que estamos haciendo es redirigir el Welcome.do a la página ejercicios.jsp que está en la carpeta pages
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 41
para la css estilo.css añadido
.enlace { height:40px; }
CÓDIGO DE LA PÁGINA EJERCICIOS.JSP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title>Ejercicios</title> <html:base/> <link rel="stylesheet" type="text/css" href="../css/estilo.css" /> </head> <body> <div id="contenedor"> <h2> <bean:message key="ejercicios"/> </h2> <div class="enlace"> <html:link page="/pages/login.jsp"> 1) formulario login ActionFom </html:link> </div> <div class="enlace"> <html:link page="/pages/formulariodinamico.jsp"> 2) formulario dinámico </html:link> </div> <div class="enlace">
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 42
28 29 30 31 32 33 34 35 36
<html:link page="/pages/formdinavalidacion.jsp"> 3) formulario dinámico validación </html:link> </div> <div id="pie"> <p> www.railsymas.com </p> </div> </div> </body> </html:html>
Cofiguración en el struts‐config.xml del bean dynavalidatorform tenemos el nombre del bean en el atributo name y en el atributo type la clase a la que pertenece, después tenemos los mismos campos que en el formulario dynaactionform, nombre, domicilio y edad inicializado a 18
1 2 3 4 5 6
<form‐bean name="dinamicoValidacion" type="org.apache.struts.validator.DynaValidatorForm"> <form‐property name="nombre" type="java.lang.String" /> <form‐property name="domicilio" type="java.lang.String" /> <form‐property name="edad" type="java.lang.Integer" initial="18" /> </form‐bean>
Si nos fijamos en el fichero de configuración struts‐config.xml viene lo siguiente descomentado ya en el proyecto en blanco struts‐blank.xml del que partimos
1 2 3 4
<plug‐in className="org.apache.struts.validator.ValidatorPlugIn"> <set‐property property="pathnames" value="/org/apache/struts/validator/validator‐rules.xml, /WEB‐INF/validation.xml"/> </plug‐in>
Struts utiliza dos ficheros xml de configuración uno que vamos a introducir datos validation.xml y el otro lo dejaremos como está y comentaremos más adelante validator‐rules.xml donde tenemos la configuración tipos de campos (entero real etc ) presencia o no de un campo todo ya proporcionado por el framework struts. Estos dos ficheros estan en la carpeta web‐inf del proyecto.
Dentro del fichero validation.xml introducimos lo siguiente:
1 2 3 4 5 6 7 8 9 10 11 12
<formset> <form name="dinamicoValidacion"> <field property="nombre" depends="required"> <arg key="campo.nombre"/> </field> <field property="domicilio" depends="required">
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 43
13 14 15 16 17
<arg key="campo.domicilio"/> </field> </form> </formset>
Como ya venía este fichero con bloques declarados nos fijamos que tiene la siguiente estructura y dentro se declara el formulario con sus campos . El name del form tiene que ser el mismo del nombre que el declarado en la sección formbean para el formulario de validación dinámica. Solamente para los dos campos del formulario nombre y domicilio se pide que sean rellenados para ello ponemos depends=”required” esto funciona ya que el fichero validator‐rules.xml lo tiene así establecido.
CÓDIGO DE LA PÁGINA FORMDINAVALIDACION.JSP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%><!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <html:html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title><bean:message key="titulo.dinamico"/></title> <html:base/> <link rel="stylesheet" type="text/css" href="../css/estilo.css" /> </head> <body> <div id="contenedor"> <h2><bean:message key="titulo.dinamicoValidacion"/></h2> <div id="errores"> <html:errors/> </div> <div id="imagen"> <html:img srcKey="dinamicoValidacion.registro.imagen" titleKey="dinamicoValidacion.registro.imagen.alt"/> </div> <div id="contenido"> <html:form action="dinamicoValidacion" focus="nombre" styleId="formulario" method="post"> <div class="campo"> <bean:message key="login.nombre"/> <html:text property="nombre"/> </div> <div class="campo"> <bean:message key="login.domicilio"/> <html:text property="domicilio"/> </div> <div class="campo"> <bean:message key="login.edad" /> <html:password property="edad" maxlength="3" size="3"/> </div>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 44
40 41 42 43 44 45 46 47 48
<html:submit styleClass="boton" value="enviar"/> <html:cancel styleClass="boton" value="cancelar"/> </html:form> </div> <div id="pie"> <p> www.railsymas.com </p> </div> </div> </body> </html:html>
IMAGEN DEL FORMULARIO
Se puede ver como al enviar el formulario ya valida la presencia de los campos en este caso se envió vacío y nos muestra el aviso de los dos campos
Código del formulario de cancelación es el mismo código que en el formulario DynaActionForm ya que no es necesario tocarlo pero se vuelve a incluir aquí para este ejemplo código de cancelada2.jsp
1 2 3 4 5 6 7
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%><%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 45
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
<meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title> <bean:message key="cancelada.titulo"/></title> <html:base/> <link rel="stylesheet" type="text/css" href="../css/estilo.css" /> </head> <body> <div id="contenedor"> <h2> <bean:message key="cancelada.login"/> </h2> <div id="imagen"> <html:img srcKey="cancelada.imagen" titleKey="cancelada.imagen.alt"/> </div> <div id="mensaje"> <bean:message key="cancelada.mensaje"/> <div class="campo"> <html:link page="/pages/ejercicios.jsp" > Volver al menú de ejercicios </html:link> </div> </div> <div id="pie"> <p> www.railsymas.com </p> </div> </div> </body> </html:html>
CÓDIGO FUENTE DE LA PÁGINA PERSONALES DATOSPERSONALES2.JSP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%><%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title><bean:message key="titulo.dinamicoValidacion"/></title> <html:base/> <link rel="stylesheet" type="text/css" href="../css/estilo.css" /> </head> <body> <div id="contenedor"> <h2>Bienvenido <bean:write name="dinamicoValidacion" property="nombre"/></h2> <div id="imagen"> <html:img srcKey="dinamicoValidacion.imagen" titleKey="dinamicoValidacion.imagen.alt"/> </div> <div id="mensaje"> <bean:message key="dinamicoValidacion.mensaje"/> <div class="campo">
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 46
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
<bean:write name="dinamicoValidacion" property="nombre"/> </div> <div class="campo"> <bean:write name="dinamicoValidacion" property="domicilio"/> </div> <div class="campo"> <bean:write name="dinamicoValidacion" property="edad"/> </div> </div> <div id="pie"> <p>www.railsymas.com </p> </div> </div> </body> </html:html>
El formulario se ha enviado correctamente y se muestran los datos pasando nombre:manolo domicilio: casa de manolo edad 59
COFIGURACIÓN DEL ACTION EN EL FICHERO STRUTS‐CONFIG.XML
1 2 3 4 5 6 7 8
<action path="/dinamicoValidacion" type="acciones.AccionDinamicaValidacion" scope="request" name="dinamicoValidacion" validate="true" input="/pages/formdinavalidacion.jsp" >
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 47
9 10 11 12 13 14 15
<set‐property property="cancellable" value="true" /> <forward name="cancelada" path="/pages/cancelada2.jsp" /> <forward name="datospersonales" path="/pages/datospersonales2.jsp"/> </action>
CLASE ACTION EN EL PACKAGE DE ACCIONES
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
package acciones; import org.apache.struts.action.Action; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionForm; import org.apache.struts.validator.DynaValidatorForm; public class AccionDinamicaValidacion extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { DynaValidatorForm formularioValidacion = (DynaValidatorForm) form; ActionForward reenvio = null; if (isCancelled(request)) { //log.debug("Se ha pulsado el boton cancel"); return mapping.findForward("cancelada"); } reenvio = mapping.findForward("datospersonales"); return reenvio; } }
CÓDIGO DE MESSAGERESOURCES_ES_ES.PROPERTIES
1 2 3 4 5 6 7 8 9
#titulo página ejercicios ejercicios = Ejercicios #claves para la página de formulario titulo.dinamicoValidacion = formulario dinámico ValidacióndinamicoValidacion.imagen = ../imagenes/iconovalidacion.png dinamicoValidacion.imagen.alt = icono validaci&oaccuten dinamicoValidacion.mensaje = Te has registrado correctamente
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 48
10 11 12 13 14 15 16 17
dinamicoValidacion.registro.imagen = ../imagenes/usuario2.pngdinamicoValidacion.registro.imagen.alt = icono usuario campo.nombre = el nombre campo.domicilio = el domicilio errors.required={0} es requerido.
Vemos como en el fichero de propiedades pares, clave valor properties viene “error.required” donde {0} se sustituye por el valor campo domicilio segun el fichero validation.xml en ” ” para el caso de domicilio lo mismo ocurre con el nombre.
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 49
STRUTS DISPATCHACTION ECLIPSE
DispatchAction, la clase DispatchAction permite múltiples operaciones en una sola clase, la idea es no tener que hacer para cada acción una clase action distinta que procese una petición concreta.
Si tenemos en un formulario por ejemplo con acceso a una base de datos de libros, puede que tengamos diversos botones en esa vista, para poder acceder al listado o bien acceder a otro menú donde podemos editar determinados campos del registro o calcular el volumen de ventas. Si utilizamos la clase action tendríamos que hacer que cada una de esas acciones de la vista fuese a una clase distinta que la procesase.
Para la utilización de la clase DispatchAction, necesitamos crear una clase que amplie y añada un método para cada función que se necesite.
Habíamos visto los links en struts con el atributo pages apuntando hacia una página jsp en la página de ejercicios incluimos un nuevo enlace hacia el formulario para dispatchaction pero en este caso utilizamos el atributo “action” de la etiqueta “hml:link”. Esto permite hacer un enlace a la accion que a su vez será reenviada a una página jsp.
CÓDIGO PARA LA CONFIGURACIÓN DEL ARCHIVO STRUTS‐CONFIG.XML
1 2 3
<action path="/dispatchAccion" forward="/pages/formulariodispatch.jsp" />
CÓDIGO QUE AÑADIMOS AL ARCHIVO EJERCICIOS.JSP
1 2 3 4
<div class="enlace"> <html:link action="/dinamicolibro"> 4) formulario dispatchAction </html:link> </div>
Imagen para Ejercicios.jsp
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 50
DECLARACIÓN DEL FORMULARIO DINÁMICO EN EL FICHERO STRUTS‐CONFIG.XML
1 2 3 4 5 6 7 8 9 10 11
<!‐‐ ================================ Form Bean Definitions ‐‐‐> <form‐bean name="dinamicolibro" type="org.apache.struts.validator.DynaValidatorForm"> <form‐property name="titulo" type="java.lang.String" /> <form‐property name="autor" type="java.lang.String" /> <form‐property name="cambio" type="java.lang.String" /> </form‐bean>
El bean dinámico tiene dos propiedades titulo y autor que se comprueban que existan
Configuración del action para el fichero de recogida de datos del libro el action “dinamicolibro”
el nombre de la accion viene determinada por el atributo path dinamico libro la clase de accion viene determinada por el atributo type el atributo scope determina el ámbito en este caso de petición el atributo name hace referencia al nombre del bean al que esta asociada la acción el atributo validate a true indica que se va a establecer una validación de los campos del formulario dinámico el atributo input indica cual es el formulario de entrada para desarrollar la acción y en caso de validación cual es la jsp que se muestra. Los forwards para realizar los reenvíos correspondientes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
<action path="/dispatchAccion" forward="/pages/formulariodispatch.jsp" /> <action path="/dinamicolibro" type="acciones.AccionDispatch" scope="request" name="dinamicolibro" validate="true" input ="/pages/formulariodispatch.jsp" parameter="method" > <set‐property property="cancellable" value="true" /> <forward name="cancelada" path="/pages/cancelada2.jsp"/> <forward name="editarlibros" path="/pages/edicion.jsp"/> </action>
CONFIGURACIÓN DEL ACTION EN EL STRUTS‐CONFIG.XML ACTION “DINAMICOLIBRO2″
1 2 3 4 5
<action path="/dinamicolibro2" type="acciones.AccionDispatch" scope="request"
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 51
6 7 8 9 10 11 12 13
name="dinamicolibro" validate="false" parameter="method"> <set‐property property="cancellable" value="true"/> <forward name="cancelada" path="/pages/cancelada2.jsp"/> <forward name="datoslibro" path="/pages/datoslibros.jsp"/> </action>
Como estamos haciendo un formulario dinámico y lo queremos validar, tenemos que crear las siguientes reglas en el fichero validation.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
<formset> <form name="dinamicolibro"> <field property="titulo" depends="required"> <arg key="libro.titulo" /> </field> <field property="autor" depends="required"> <arg key="libro.autor" /> </field> </form> </formset>
el nombre del formulario en form name=”dinamicolibro” es el mismo que el name de la configuración del bean declarado en el struts‐config.xml
Imagen del fichero formulariodispatch.jsp, a la introducción de datos del libro
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 52
Imagen del fichero formulariodispatch.jsp
Imagen resultado del envío de los datos
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 53
Introducimos titulo2 en el campo de titulo
resultado final
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 54
import org.apache.struts.actions.DispatchAction;
Código del fichero action de la clase dispatchAction importamos import org.apache.struts.actions.DispatchAction, esa línea de código solamente con el proyecto de struts para la versión 1.3.10 que es con la que se estan haciendo todos los ejemplos da error ya que el proyecto en blanco no la reconoce. Para solventar este problema, tenemos que importar del directorio donde descomprimimos el proyecto struts, el fichero jar lstruts‐extras‐1.3.10.jar dentro del fichero lib del proyecto web eclipse.
“lib/struts‐extras‐1.3.10.jar”,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
package acciones; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionForward; import org.apache.struts.actions.DispatchAction; import org.apache.struts.validator.DynaValidatorForm; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class AccionDispatch extends DispatchAction { private ActionForward envio; private DynaValidatorForm formulario; private String titulo; private String autor; //creamos los métodos que responden a las acciones public ActionForward crear ( ActionMapping mapping, ActionForm form,
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 55
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
HttpServletRequest request, HttpServletResponse response ) throws Exception { //si hemos cancelado la ejecución mandamos al jsp de cancelación if (isCancelled(request)) { envio = mapping.findForward("cancelada"); } else { //recuperamos los datos del formulario bean dinámico Validator formulario = (DynaValidatorForm) form; titulo = formulario.getString("titulo"); autor = formulario.getString("autor"); System.out.println(titulo); envio = mapping.findForward("editarlibros"); } return envio; } public ActionForward EditarTitulo (ActionMapping mapping, ActionForm form, HttpServletRequest resquest, HttpServletResponse response) throws Exception { //recuperamos los datos del formulario bean dinámico Validator formulario = (DynaValidatorForm) form; String cadena = "Se ha cambiado "+this.titulo+" por "+formulario.getString("titulo"); formulario.set("cambio",cadena); //recargamos el formulario con el valor guardado formulario.set("autor",this.autor); envio = mapping.findForward("datoslibro"); return envio; } public ActionForward EditarAutor (ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { //recuperamos los datos del formulario bean dinámico Validator //recuperamos los datos del formulario bean dinámico Validator formulario = (DynaValidatorForm) form; String cadena = "Se ha cambiado "+this.autor+" por "+formulario.getString("autor");
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 56
80 81 82 83 84 85 86 87 88 89 90 91
formulario.set("cambio",cadena); //recargamos el formulario con el formulario.set("titulo",this.titulo); envio = mapping.findForward("datoslibro"); return envio; } }
CÓDIGO FUENTE DEL FICHERO DEL FICHERO FORMULARIODISPATCH.JSP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <html:html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title><bean:message key="titulo.libro"/></title> <html:base/> <link rel="stylesheet" type="text/css" href="../css/estilo.css" /> </head> <body> <div id="contenedor"> <h2><bean:message key="titulo.libro"/></h2> <div id="errores"> <html:errors/> </div> <div id="imagen"> <html:img srcKey="libro.imagen" titleKey="libro.imagen.alt"/> </div> <div id="contenido"> <html:form action="dinamicolibro" focus="nombre" styleId="formulario" method="post"> <div class="campo"> <bean:message key="libro.titulo"/> <html:text property="titulo" /> </div> <div class="campo"> <bean:message key="libro.autor"/> <html:text property="autor" /> </div> <html:hidden property="method" value="crear"/> <html:submit styleClass="boton" value="enviar"/> <html:cancel styleClass="boton" value="cancelar"/> <html:reset styleClass="boton" value="borrar"/>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 57
42 43 44 45 46 47 48 49
</html:form> </div> <div id="pie"> <p> www.railsymas.com </p> </div> </div> </body> </html:html>
CÓDIGO FUENTE DEL FICHERO EDICION.JSP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%> <%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title><bean:message key="editar.titular"/></title> <html:base/> <link rel="stylesheet" type="text/css" href="../css/estilo.css" /> </head> <body> <div id="contenedor"> <h2> <bean:message key="editar.titular"/></h2> <div id="imagen"> <html:img srcKey="editar.imagen" titleKey="editar.imagen.alt"/> </div> <div id="mensaje"> <bean:message key="editar.mensaje"/> <html:form action="dinamicolibro2" styleClass="formulario" method="post"> <div class="campo"> <bean:message key="editar.valor" /> <br/> <bean:write name="dinamicolibro" property="titulo"/> </div> <html:text property="titulo"/> <html:hidden property="method" value="EditarTitulo"/> <html:submit styleClass="boton" value="editar"/> </html:form> <html:form action="dinamicolibro2" styleClass="formulario" method="post"> <div class="campo" class="flotaizquierda"> <bean:message key="editar.valor" /> <br/> <bean:write name="dinamicolibro" property="autor"/> </div> <html:text property="autor"/>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 58
46 47 48 49 50 51 52 53 54 55 56 57 58 59
<html:hidden property="method" value="EditarAutor"/> <html:submit styleClass="boton" value="editar"/> </html:form> </div> <div id="pie"> <p>www.railsymas.com </p> </div> </div> </body> </html:html>
CÓDIGO FUENTE DEL FICHERO DATOSLIBROS.JSP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%><%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title><bean:message key="resultado.mensaje"/></title> <html:base/> <link rel="stylesheet" type="text/css" href="../css/estilo.css" /> </head> <body> <div id="contenedor"> <h2><bean:message key="resultado.mensaje"/></h2> <div id="imagen"> <html:img srcKey="resultado.imagen" titleKey="resultado.imagen.alt"/> </div> <div id="mensaje"> <bean:message key="resultado.mensaje"/> <div class="campo"> <bean:write name="dinamicolibro" property="titulo"/> </div> <div class="campo"> <bean:write name="dinamicolibro" property="autor"/> </div> <div class="campo"> <bean:write name="dinamicolibro" property="cambio"/> </div> </div> <div id="pie"> <p>www.railsymas.com </p> </div> </div> </body> </html:html>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 59
IBATIS PROYECTO WEB ECLIPSE
Lo primero, como bien dice la wikipedia ibatis es un marco de trabajo desarrollado por apache que se ocupa de la capa de persistencia, situándose entre la capa de negocio y la base de datos. Ibatis esta disponible para java .net y ruby on rails.
Ibatis cumple una función similar a la de hibernate, algunos desarrolladores consideran a ibatis una alternativa por su sencillez y por no presentar un lenguaje específico para consultas.
En la página web del proyecto ibatis enlace proyecto ibatis
Recordar que este ejemplo esta realizado en linux ubuntu pero que es totalmente compatible con windows.
Descargar la versión 2.3.0 o la versión 2.3.4 con las que se ha probado el ejemplo, una vez descargado y desempaquetado el proyecto dentro de la carpeta lib tenemos un fichero .jar con la versión correspondiente. Ese fichero debemos del importarlo el directorio lib de nuestro proyecto web dinámico de eclipse.
Partimos de la situación del ejemplo jdbc eclipse, nos habíamos descargado mysql, y el jar driver para jdbc creando la base de datos libros_jdbc, con una tabla llamada libros. En ese ejemplo creabamos un servlet que por método get mostraba un formulario para enviar después los datos por método post, insertar los datos y mostrar un listado de lo almacenado en la tabla.
Enlace al ejemplo anterior Conexión a bases de datos j2ee jdbc eclipse
CLASE BEAN LIBRO.JAVA
1 2 3 4 5 6
package conexion; public class Libro { private int id_libro; private String titulo_libro;
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 60
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
private String autor_libro; private String tematica_libro; public int getId_libro() { return id_libro; } public void setId_libro(int id_libro) { this.id_libro = id_libro; } public String getTitulo_libro() { return titulo_libro; } public void setTitulo_libro(String titulo_libro) { this.titulo_libro = titulo_libro; } public String getAutor_libro() { return autor_libro; } public void setAutor_libro(String autor_libro) { this.autor_libro = autor_libro; } public String getTematica_libro() { return tematica_libro; } public void setTematica_libro(String tematica_libro) { this.tematica_libro = tematica_libro; } }
Ficheros de configuración para ibatis son tres y los pondremos en un package ibatisMap
El fichero basedatos.java es el servlet del anterior ejemplo jdbc el utilizado para ibatis es BaseDatosIbatis.java
En el propio proyecto de apache ibatis tienen tutoriales indicando la funcionalidad de cada uno de los ficheros necesarios para ibatis
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 61
Creamos un fichero xml para el mapeo del bean Libro “Libro.xml”, este fichero contiene el conjunto de consultas que van a ser utilizadas para el bean asociado a la tabla libros
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
<?xml version="1.0" encoding="UTF‐8"?><!DOCTYPE sqlMap PUBLIC "‐//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql‐map‐2.dtd"> <sqlMap namespace="Libro"> <select id="getLibro" parameterClass="int" resultClass="conexion.Libro"> SELECT id as id_libro, titulo as titulo_libro, autor as autor_libro, tematica as tematica_libro FROM libros WHERE id = #value# </select> <insert id="introducirLibro" parameterClass="conexion.Libro"> INSERT INTO libros (id,titulo,autor,tematica) VALUES (#id_libro#,#titulo_libro#,#autor_libro#,#tematica_libro#) </insert> <select id="getLibros" resultClass="conexion.Libro"> SELECT id as id_libro, titulo as titulo_libro, autor as autor_libro, tematica as tematica_libro FROM libros </select> </sqlMap>
fichero de propiedades para el ejemplo, sustituye a lo que se hacia en el anterior ejemplo jdbc al cargar el driver
1 2 3 4
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/libros_jdbcusername=root password=root
FICHERO DE CONFIGURACIÓN DE SQL MAP
1 2 3 4 5 6 7 8 9
<?xml version="1.0" encoding="UTF‐8"?><!DOCTYPE sqlMapConfig PUBLIC "‐//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql‐map‐config‐2.dtd"> <sqlMapConfig> <properties resource="ibatisMap/sqlMapConfig.properties" /> <settings cacheModelsEnabled="true"
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 62
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
enhancementEnabled="true" lazyLoadingEnabled="true" maxRequests="32" maxSessions="10" maxTransactions="5" useStatementNamespaces="false" /> <transactionManager type="JDBC"> <dataSource type="SIMPLE"> <property name="JDBC.Driver" value="${driver}"/> <property name="JDBC.ConnectionURL" value="${url}"/> <property name="JDBC.Username" value="${username}"/> <property name="JDBC.Password" value="${password}"/> </dataSource> </transactionManager> <sqlMap resource="ibatisMap/Libro.xml"/> </sqlMapConfig>
Imagen de los jars utilizados
Creamos una clase dentro del package conexion con el nombre BaseDatosIbatis.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
package conexion; import java.io.IOException; import java.sql.SQLException; import java.io.Reader; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ibatis.sqlmap.client.SqlMapClient; import com.ibatis.sqlmap.client.SqlMapClientBuilder; import com.ibatis.common.resources.Resources; import java.io.PrintWriter; import java.util.List; import java.util.Iterator; /** * Servlet implementation class for Servlet: BaseDatosIbatis * */ public class BaseDatosIbatis extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { static final long serialVersionUID = 1L;
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 63
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
private SqlMapClient sqlMap = null; /* (non‐Java‐doc) * @see javax.servlet.http.HttpServlet#HttpServlet() */ public BaseDatosIbatis() { super(); } public void init() throws ServletException { super.init(); try { String recursos = "ibatisMap/SqlMapConfigLibro.xml"; Reader leer = Resources.getResourceAsReader(recursos); sqlMap = SqlMapClientBuilder.buildSqlMapClient(leer); } catch ( Exception e) { System.out.print("error mapeo: "+e.getMessage()); } } /* (non‐Java‐doc) * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto‐generated method stub //mostramos el listado con el método get response.setContentType("text/html"); //preparamos el objeto de salida PrintWriter salida = response.getWriter(); //creamos la salida salida.print("<!DOCTYPE html PUBLIC '‐//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n"); salida.print("<html>\n"); salida.print("<head>\n"); salida.print("<link rel='stylesheet' type='text/css' href='css/estilo.css'/>\n"); salida.print("</head>\n"); salida.print("<body>\n"); salida.print("<div id='contenedor'>\n"); salida.print("<h2> Libros jdbc </h2>"); salida.print("<div id='imagen'>");
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 64
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
salida.print("<img src='imagenes/registro.png' title='carpeta'/>"); salida.print("</div>"); salida.print("<form action='BaseDatosIbatis' method='post'>\n<br/>"); salida.print("<label>Titulo</label>\n<br/>"); salida.print("<input type='text' name='titulo'/>\n<br/>"); salida.print("<label>Autor</label>\n<br/>"); salida.print("<input type='text' name='autor'/>\n<br/>"); salida.print("<label>Tematica</label>\n<br/>"); salida.print("<input type='text' name='tematica'/>\n<br/>"); salida.print("<input class='boton' type='submit' value='enviar'/>\n<br/>"); salida.print("</form>\n<br/>"); salida.print("<div id='pie'>"); salida.print("<p> www.railsymas.com </p>"); salida.print("</div>"); salida.print("</div>\n"); salida.print("</body>\n<br/>"); salida.print("</html>"); } /* (non‐Java‐doc) * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto‐generated method stub String titulo = request.getParameter("titulo"); String autor = request.getParameter("autor"); String tematica = request.getParameter("tematica"); response.setContentType("text/html"); PrintWriter salida = response.getWriter(); //creamos el objeto libro Libro libro = new Libro(); libro.setAutor_libro(autor); libro.setTematica_libro(tematica); libro.setTitulo_libro(titulo); libro.setId_libro(0); //insertamos en la base de datos el objeto libro try { //insertamos los datos recibidos de sqlMap.insert("introducirLibro", libro); //recuperamos los datos de la base de datos List <Libro> resultado = sqlMap.queryForList("getLibros");
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 65
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
//mostramos el resultado salida.print("<!DOCTYPE html PUBLIC '‐//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n"); salida.print("<html>\n"); salida.print("<head><title>Mostramos los datos</title></head>\n"); salida.print("<link rel='stylesheet' type='text/css' href='css/estilo.css'/>\n"); salida.println("<body>"); salida.print("<div id='contenedor'>\n"); salida.print("<h2> Libros jdbc </h2>"); salida.println("<table id='tabla'>"); salida.println("<tr>"); salida.println("<th>titulo</th><th>autor</th><th>tematica</th>"); salida.println("</tr>"); Iterator <Libro> iterador = resultado.iterator(); while (iterador.hasNext()) { Libro auxLibro = (Libro) iterador.next(); salida.println("<tr>"); salida.println("<td class='impar'>"+auxLibro.getTitulo_libro()+"</td>"); salida.println("<td class='par'>"+auxLibro.getAutor_libro()+"</td>"); salida.println("<td class='impar'>"+auxLibro.getTematica_libro()+"</td>"); salida.println("</tr>"); } salida.println("</table>"); salida.print("<div id='pie'>"); salida.print("<p> www.railsymas.com </p>"); salida.print("</div>"); salida.print("</div>\n"); salida.println("</body>"); salida.println("</html>"); } catch (SQLException e) { System.out.print("error de consulta "+e.getMessage()); } } }
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 66
STRUTS TILES PROYECTO WEB ECLIPSE
Los tiles son plantillas que utiliza struts para la organización de la estructura visual de las vistas de un proyecto web. En realidad struts no hace más que integrar en su framework algo que ya existía en j2ee, que eran las plantillas con jsp.
Como ya se hizo en un ejemplo de j2ee utilizabamos la directiva <%@include file="xxxx" %> para incluir contenido estático y para la inclusión dinámica utizabamos <%@include page="xxx" %>. esto último como recordatorio j2ee.
Una vez creada la plantilla la podemos reutilizar para cualquier página que tenga dicho formato y así no tener que escribir todo código cada vez que se hace una nueva página.
Al igual que en los anteriores post, añadimos un nuevo ejercicio a la lista, en este caso para struts‐tiles para ello en el fichero ejercicios.jsp, añadimos el siguiente enlace para la acción plantillas.
1 2 3 4
<div class="enlace"> <html:link action="/plantillas"> 5) struts tiles </html:link> </div>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 67
Recordar estamos con la versión 1.3.10 y esta versión tenemos un fichero de configuración llamado struts‐config.xml,
Vemos como el link de la página de los ejercicios va la acción plantillas, en la sección actionMapping del fichero de configuración struts‐config.xml
1 2 3
<action path="/plantillas" forward="plantillatiles"/>
Dentro del proyecto creamos una carpeta tiles, donde creamos las páginas jsp que van a intervenir en el proyecto
En estas páginas jsp hay una que es especialmente importante código de pantilla.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <%@taglib uri="http://struts.apache.org/tags‐tiles" prefix="tiles" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title><tiles:getAsString name="titulo"/></title> <html:base/> <link type="text/css" rel="stylesheet" href="../css/estiloplantilla.css"/> </head> <body> <div id="contenedor"> <div id="cabecera"> <tiles:insert attribute="cabecera"/> </div> <div id=" contendido "> <div id="menu"> <tiles:get name="menu"/> </div> <div id=" contenido "> <tiles:get name="cuerpo"/>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 68
26 27 28 29 30 31 32
</div> </div> <div id="pie"> <tiles:get name="pie"/> </div> </div> </body> </html:html>
Imagen de la plantilla
Los diferentes tiles, fragmentos de páginas jsp como se utilizan etiquetas de struts es necesario integrar la libreria html en todas ellas, recordar que estan ubicadas tal como la imagen
Código de cabecera.jsp
1 2 3 4
<%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <div id="imagencabecera"> <html:img srcKey="imagen.cabecera" altKey="imagen.cabecera.alt"/> </div>
Código de menu.jsp
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 69
1 2 3 4 5 6
<%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <ul id="menu_lateral"> <li><html:link action="/objetos"> Objetos </html:link> </li> <li><html:link action="/personajes" > Personajes </html:link> </li> </ul> <html:img srcKey="imagen.libros" altKey="imagen.libros.alt"/>
Código de cuerpo.jsp
1 2 3 4 5 6
<%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <p> Ejemplo de desarrollo con struts‐tiles, tenemos una plantilla base y diferentes definiciones de página en un fichero xml llamado tiles‐def.xml </p> <html:img srcKey="imagen.lapices" altKey="imagen.lapices.alt"/>
Código de pie.jsp
1 2 3 4 5 6
<%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %><p id="pizquierda"> <html:link action="/Welcome">Ejercicios </html:link>|<html:link action="/plantillas"> Plantilla </html:link>| <html:link action="/objetos"> Objetos</html:link> |<html:link action="/personajes"> Personajes </html:link> </p> <p id="pderecha"> @CopyRight railsymas.com </p>
Creamos dos nuevas páginas jsp para las vistas personajes y objetos
Código de personajes.jsp
1 2 3 4 5 6
<%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <div id="imagenes"> <p> Personajes </p> <html:img srcKey="imagen.personaje1" altKey="imagen.personaje1.alt"/> <html:img srcKey="imagen.personaje2" altKey="imagen.personaje2.alt"/> </div>
Código de la página objetos.jsp
1 2 3 4 5 6
<%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <div id="imagenes"> <p> Objetos </p> <html:img srcKey="imagen.objeto1" altKey="imagen.objeto1.alt"/> <html:img srcKey="imagen.objeto2" altKey="imagen.objeto2.alt"/> </div>
fichero de propiedades
1 2 3
#tiles imagen.cabecera = ../imagenes/cabecera2.png imagen.cabecera.alt = imagen cabecera
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 70
4 5 6 7 8 9 10 11 12 13 14 15
imagen.lapices = ../imagenes/lapices.pngimagen.lapices.alt = lápices imagen.libros = ../imagenes/libros.png imagen.libros.alt = libros imagen.objeto1 = ../imagenes/candado.png imagen.objeto1.alt = candado.png imagen.objeto2 = ../imagenes/impresora.png imagen.objeto2.alt = impresora.png imagen.personaje1 = ../imagenes/personachat.pngimagen.personaje1.alt = personachat.png imagen.personaje2 = ../imagenes/personajes.png imagen.personaje2.atl = personajes.png
fichero de configuración de las acciones struts‐config.xm en la sección action‐mapping
1 2 3 4 5 6 7 8 9 10 11 12 13
<action path="/plantillas" forward="plantillatiles"/> <action path="/objetos" forward="plantillaobjetos" /> <action path="/personajes" forward="plantillapersonajes" />
Tenemos dos posibilidades establecer las definiciones mediante jsp o bien mediante un fichero de configuración xml denominado tiles‐def.xml dentro de la carpetan web‐inf del proyecto struts
En el siguiente post para la segunda parte de este ejercicio se verá el fichero de configuración antes citado y la explicación más detallada así como las diferentes capturas de las vistas objetos y personajes.
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 71
STRUTS TILES PROYECTO WEB ECLIPSE 2 PARTE
Como se puede observar las dos imágenes siguen teniendo un aspecto similar al de la plantilla inicial. Lo único que cambia es la página jsp que esta asignada al div de cuerpo del esquelo de la pantilla.jsp, ese es el objetivo de los tiles proporcionar un esquema visual común a un conjunto de páginas.
Dentro del struts‐config.xml tenemos una sección ya preestablecida, solamente hay que descomentarla
1 2 3 4 5 6
<plug‐in className="org.apache.struts.tiles.TilesPlugin"> <set‐property property="definitions‐config" value="/WEB‐INF/tiles‐defs.xml" /> <set‐property property="definitions‐debug" value="2"/> <set‐property property="moduleAware" value="true" /> </plug‐in>
como se puede observar en esta sección se hace referencia al archivo xml ubicado en web‐inf/tiles‐defs.xml, se trata del fichero xml que tiene la decleración de las definiciones de las vistas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
<?xml version="1.0" encoding="UTF‐8"?> <!DOCTYPE tiles‐definitions PUBLIC "‐//Apache Software Foundation//DTD Tiles Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/tiles‐config_1_1.dtd"> <tiles‐definitions> <definition name="${YOUR_DEFINITION_HERE}"> </definition> <definition name="plantillatiles" path="/tiles/plantilla.jsp"> <put name="titulo" value="plantilla struts" type="string"/> <put name="cabecera" value="cabecera.jsp" type="page"/> <put name="menu" value="menu.jsp" type="page"/> <put name="cuerpo" value="cuerpo.jsp" type="page"/> <put name="pie" value="pie.jsp" /> </definition> <definition name="plantillaobjetos" extends="plantillatiles"> <put name="titulo" value="plantilla para objetos" type="string" /> <put name="cuerpo" value="objetos.jsp" type="page" /> </definition> <definition name="plantillapersonajes" extends="plantillatiles"> <put name="titulo" value="plantilla para personajes" type="string" /> <put name="cuerpo" value="personajes.jsp" type="page" /> </definition> </tiles‐definitions>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 72
La plantilla tiles plantilla.jsp era la página jsp que contiene el esqueleto de la plantilla, se corresponde con la definición del name=plantillatiles, este nombre es aprovechado por struts para hacer referencia a la plantilla desde el struts‐config.xml.
Como arranca la plantilla en cuanto al proceso de ejecución. Partimos como siempre de la página de ejercicios en dicha página hay un enlace a un action que es recogido por struts‐config.xml ese action lo vuelvo a poner
1 2 3
<action path="/plantillas" forward="plantillatiles"/>
Ese action era plantillas.do y donde se hace el reenvío al forward plantillatiles que es justamente el valor del atributo name de las definiciones de tiles‐def.xml con el path “tiles/plantillas.jsp” el resto de las jsp de la definición estan ya dentro de la carpeta tiles al mismo nivel.
Un error típico que puede ocurrir, es declarar la página jsp plantillas.jsp y llamarla directamente en ese caso nos da múltiples errores, varios errores actionservlet y un error de contexto indicando que está vacío.
La definición del fichero tiles‐def.xml es la que alimenta la plantilla.jsp, indicando en el name la cabecera , menú , cuerpo y pie la página jsp que le corresponde a cada cual mediante el atributo value. También hay un atributo opcional type que indica el tipo de valor, hemos utilizado dos pages y string, este ultimo para indicar el título de la página.
Como se puede apreciar en el ejemplo tanto desde la primera parte como la segunda existen tres vistas, la primera que esta en el anterior post y corresponde con la plantilla inicial y la vista de objetos y personajes.
Si queremos utilizar parte del layout de las plantillas pero haciendo un cambio para tener una vista nueva ejemplo objetos no tenemos más que hacer una herencia por eso en la definición del archivo tiles‐def.xml nos viene un name=plantillaobjeto que hereda “extends” de plantillatiles, todo menos el cuerpo y el título.
Mediante el fichero xml tiles‐def.xml hacemos herencia y además estamos sobreescribiendo como en POO una parte de la plantilla, en este caso el cuerpo.
En el struts‐config.xml se incluye lo siguiente, el controlador proporcionado por el framework Tiles en lugar del controlador de Struts. Este controlador es una versión extendida del controlador de Struts.
Si lo quitamos o descomentamos nos sale un error de servlet‐exception
1 2 3
<!‐‐ ============================================= Controller Configuration ‐‐> <controller processorClass="org.apache.struts.tiles.TilesRequestProcessor"/>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 73
Imagen la vista de objetos
Imagen de la vista de personajes
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 74
TUTORIAL HTML STRUTS TAGS
En ejemplos anteriores, se había utilizado unas etiquetas que podían resultar diferentes si venimos de otros lenguajes de programación web.
Struts utiliza unas etiquetas html muy similares a las de html pero con algunas variantes. Siempre se antepone la etiqueta html, de tal forma que para indicar el inicio y el fin del documento se pone y
Para su utilización en una página jsp debemos incluir la siguiente sintaxis para el caso de 1.3.10
<%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %>
el valor del atributo prefix se pone html para no equivocarse pero podría se cualquier otro nombre
html equivale a html
button equivalente a input type=button
cancel equivale a input type=subtmit”
checkbox equivale a input type=checkbox
hidden equivale a input type=hidden
img equivale a img
javascript equivale a javascript
link equivale a “a”
base base de la página
messages muestra los mensajes del idioma
multibox type checkbox pero permite un array de string de los property iguales
option equivale a option
password equivale a password
radio equivale a radio
reset equivale a reset
select equivale a select
submit equivale a type submit
text equivale a type text
textarea equivale a textarea
frame equivale a frame
form equivale a html
file equivale type file
En la descarga del proyecto struts existe una carpteta docs con html con toda la informacion referente a los tags html como bean logic tiles etc …..
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 75
TUTORIAL DE LOOKUPDISPATCHACTION STRUTS
LookupDispatchaction es otra clase de struts que complementa los ejercicios anteriores sobre formularios struts.
Habíamos visto la clase Dispatchaction en struts, que aportaba la posibilidad de realizar distintas acciones en una sola clase, añadiendo una nueva potencialidad a las clases action, las cuales solamente tenían el método service genérico para responder a las peticiones de los usuarios.
LookupDispatchaction tiene también en su configuración un parámetro parameter, que indica el nombre del método. Lookupdispatchaction tiene la ventaja que permite desde un mismo formulario poder llamar a distintos métodos.
CÓDIGO DE PÁGINA EJERCICIOS.JSP COMO LOS ANTERIORES EJEMPLOS
1 2 3
<div class="enlace"> <html:link action="/dinamicoLookup"> 6) lookupdispatchAction </html:link> </div>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 76
CONFIGURACION DEL BEAN DYNAVALIDATORFORM
1 2 3 4 5 6 7 8
!‐‐ ================================================ Form Bean Definitions ‐‐> <form‐bean name="dinamicolibro" type="org.apache.struts.validator.DynaValidatorForm"> <form‐property name="titulo" type="java.lang.String" /> <form‐property name="autor" type="java.lang.String" /> <form‐property name="cambio" type="java.lang.String" /> </form‐bean>
CONFIGURACIÓN DEL ARCHIVO STRUTS‐CONFIG.XML PARA ACTION MAPPING
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
<!‐‐ =========================================== Action Mapping Definitions ‐‐> <action path="/dinamicoLookup" forward="/pages/formularioLookup.jsp" /> <action path="/lookupDispatchAction" type="acciones.AccionLookupDispatchAction" scope="request" validate="true" name="dinamicolibro" input ="/pages/formularioLookup.jsp" parameter="method"> <set‐property property="cancellable" value="true" /> <forward name="cancelada" path="/pages/cancelada2.jsp" /> <forward name="editarlibros" path="/pages/edicion2.jsp"/> </action> <action path="/LookupDispatchAction2" type="acciones.AccionLookupDispatchAction" scope="request" validate="false" name= "dinamicolibro" parameter= "method"> <set‐property property="cancellable" value="true" /> <forward name="cancelada" path="/pages/cancelada2.jsp" /> <forward name="datoslibro" path="/pages/datoslibros.jsp"/> </action>
Configuración de la validación de los campos del bean en el fichero validation.xml dentro del tag
<form‐validation>
Como repaso desde DynaValidatorForm, se creaban unos formularios bean dinámicos, que permitían validar los campos de un formulario sin teneer que crear la clase
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 77
actionForm. En el fichero xml validation.xml se crean las reglas para que los campos sean obligatorios.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
<formset> <form name="dinamicolibro"> <field property="titulo" depends="required"> <arg key="libro.titulo" /> </field> <field property="autor" depends="required"> <arg key="libro.autor" /> </field> </form> </formset>
CONFIGURACIÓN DEL FICHERO DE PROPIEDADES PROPERTIES
1 2 3 4 5 6 7 8
#lookupdispathActionformularioLookup.cancelar = cancelar formularioLookup.crear = crear formularioLookup.editartitulo= EditarTituloformularioLookup.editarautor = EditarAutor tituloLookup.libro = LookupDispatchActionLookup.titulo = titulo Lookup.autor = autor
CÓDIGO DE LA PÁGINA JSP FORMULARIOLOOKUP.JSP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%><!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <html:html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title><bean:message key="tituloLookup.libro"/></title> <html:base/> <link rel="stylesheet" type="text/css" href="../css/estilo.css" /> </head> <body> <div id="contenedor"> <h2><bean:message key="tituloLookup.libro"/></h2> <div id="errores"> <html:errors/> </div> <div id="imagen"> <html:img srcKey="libro.imagen" titleKey="libro.imagen.alt"/> </div>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 78
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
<div id="contenido"><html:form action="lookupDispatchAction" focus="nombre" styleId="formulario" method="post"> <div class="campo"> <bean:message key="Lookup.titulo"/> <html:text property="titulo" /> </div> <div class="campo"> <bean:message key="Lookup.autor"/> <html:text property="autor" /> </div> <html:submit styleClass="boton" property="method"><bean:message key="formularioLookup.crear"/> </html:submit> <html:cancel styleClass="boton"><bean:message key="formularioLookup.cancelar"/> </html:cancel> <html:reset styleClass="boton" value="borrar"/> </html:form> </div> <div id="pie"> <p> www.railsymas.com </p> </div> </div> </body> </html:html>
CLASE LOOKUPDISPATCHACTION ACCIONLOOKUPDISPATCHACTION.JAVA
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
package acciones; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionForward; import org.apache.struts.actions.LookupDispatchAction; import org.apache.struts.validator.DynaValidatorForm; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Map; import java.util.HashMap; public class AccionLookupDispatchAction extends LookupDispatchAction { private ActionForward envio; private DynaValidatorForm formulario; private String titulo; private String autor; protected Map getKeyMethodMap () { Map map = new HashMap(); map.put("formularioLookup.editartitulo","EditarTitulo"); map.put("formularioLookup.editarautor","EditarAutor"); map.put("formularioLookup.crear","crear");
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 79
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
return map; } protected ActionForward cancelled (ActionMapping mapping,ActionForm form,HttpServletRequest request, HttpServletResponse response) throws Exception { if (isCancelled(request)){ envio = mapping.findForward("cancelada"); } return envio; } //creamos los métodos que responden a las acciones public ActionForward crear ( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response ) throws Exception { //recuperamos los datos del formulario bean dinámico Validator formulario = (DynaValidatorForm) form; titulo = formulario.getString("titulo"); autor = formulario.getString("autor"); System.out.println(titulo); envio = mapping.findForward("editarlibros"); return envio; } public ActionForward EditarTitulo (ActionMapping mapping, ActionForm form, HttpServletRequest resquest, HttpServletResponse response) throws Exception { //recuperamos los datos del formulario bean dinámico Validator formulario = (DynaValidatorForm) form; String cadena = "Se ha cambiado "+this.titulo+" por "+formulario.getString("titulo"); formulario.set("cambio",cadena); //recargamos el formulario con el valor guardado formulario.set("autor",this.autor); envio = mapping.findForward("datoslibro"); return envio; } public ActionForward EditarAutor (ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 80
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
{ //recuperamos los datos del formulario bean dinámico Validator //recuperamos los datos del formulario bean dinámico Validator formulario = (DynaValidatorForm) form; String cadena = "Se ha cambiado "+this.autor+" por "+formulario.getString("autor"); formulario.set("cambio",cadena); //recargamos el formulario con el formulario.set("titulo",this.titulo); envio = mapping.findForward("datoslibro"); return envio; } }
LookupDispatchAction, permite al igual que con dispatchaction tener varias acciones (métodos) en la misma clase de tal forma que tenemos dos formularios que llaman a la misma clase. A través de los diferentes métodos se realizan distintas acciones.
Se utiliza un HashMap para establecer un conjunto de contraseñas para los distintos métodos a usar, esas contraseñas son las ulilizadas en los botones de las páginas jsp.
Es necesario crear el método protected Map getKeyMethodMap para la creación del conjunto de claves método.
Si se quiere incluir el botón de cancelación con el uso de esta clase, la configuración en el fichero struts‐config.xml para ello no responde, por lo que hay que hacer cambios en la clase java e incluir el método cancelled para sobreescribirlo y responder al botón de cancelación.
Imagen resultado del envío de los datos
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 81
Introducimos titulo2 en el campo de titulo
resultado final
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 82
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 83
DATASOURCE STRUTS 1.2.X PROYECTO WEB ECLIPSE
Enlace al proyecto struts Datasource
El datasource, se utiliza para establecer un pool de conexiones que implementan la interface javax.sql.DataSource. Permitiendo establecer una configuración para las bases de datos utilizadas en las aplicaciones de struts, y solamente desde las clases de negocio llamar a esta configuración para poder utilizarlas.
Este tipo de configuración es válido para las versiones de struts 1.1 hasta la versión 1.2.9. Este ejemplo a diferencia de los anteriores de struts en el que se utilizaba la versión 1.3.10, está realizado con la 1.2.9.
DATASOURCE STRUTS
La declaración del datasource va dalante de los beans para la dtd struts‐config_1_2.dtd
1
2
3
4
5
6
7
8
<!DOCTYPE struts‐config PUBLIC
"‐//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
"http://jakarta.apache.org/struts/dtds/struts‐config_1_2.dtd">
<struts‐config>
<!‐‐ ============================================ Data Source Configuration ‐‐>
<data‐sources>
CONFIGURACIÓN DEL ARCHIVO STRUTS‐CONFIG.XML PARA EL DATASOURCE
1
2
3
4
5
6
7
8
9
10
<data‐sources>
<data‐source type="org.apache.tomcat.dbcp.dbcp.BasicDataSource">
<set‐property property="driverClassName" value="com.mysql.jdbc.Driver" />
<set‐property property="url" value="jdbc:mysql://localhost:3306/libros_jdbc" />
<set‐property property="username" value="root"/>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 84
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<set‐property property="password" value="root"/>
<set‐property property="maxActive" value="10"/>
<set‐property property="defaultReadOnly" value="false" />
<set‐property property="defaultAutoCommit" value="true" />
<set‐property property="validationQuery" value="SELECT COUNT(*) FROM libros" />
</data‐source>
</data‐sources>
CONFIGURACIÓN DE LOS ACTIONS PARA EL STRUTS‐CONFIG.XML
Creamos los actions para el ejemplo, simplemente redireccionamos la acción Welcome.do a la acción ‘conexión’. Si se establece la conexión correctamente se redirecciona a la página
1
2
3
4
5
6
7
8
9
10
11
12
<!‐‐ =========================================== Action Mapping Definitions ‐‐>
<action‐mappings>
<!‐‐ Default "Welcome" action ‐‐>
<!‐‐ Forwards to Welcome.jsp ‐‐>
<action
path="/Welcome"
forward="/conexion.do"/>
<action
path="/conexion"
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 85
13
14
15
16
17
18
type="accion.accionBaseDatos"
scope="request">
<forward name="satisfactoria" path="/pages/registroSatisfactorio.jsp"/>
<forward name="fallida" path="/pages/fallida.jsp"/>
</action>
CÓDIGO DE LA PÁGINA FALLIDA.JSP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<%@ page language="java" contentType="text/html; charset=ISO‐8859‐1" pageEncoding="ISO‐8859‐1"%>
<%@taglib uri="/tags/struts‐html" prefix="html" %>
<%@taglib uri="/tags/struts‐bean" prefix="bean" %>
<!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http‐equiv="Content‐Type" content="text/html; charset=ISO‐8859‐1">
<title>Conexion Fallida</title>
<html:base/>
<link rel="stylesheet" type="text/css" href="../css/estilo.css"/>
</head>
<body>
<div id="contenedor">
<div id="contenido">
<p> conexion fallida </p>
</div>
<div id="pie">
<p> www.railsymas.com </p>
</div>
</div>
</body>
</html>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 86
CÓDIGO DE LA PÁGINA REGISTRO SATISFACTORIO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<%@ page language="java" contentType="text/html; charset=ISO‐8859‐1" pageEncoding="ISO‐8859‐1"%>
<%@taglib uri="/tags/struts‐html" prefix="html" %>
<%@taglib uri="/tags/struts‐bean" prefix="bean" %>
<!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html:html>
<head>
<meta http‐equiv="Content‐Type" content="text/html; charset=ISO‐8859‐1">
<title>Consulta a la base de datos</title>
<html:base/>
<link rel="stylesheet" href="../css/estilo.css" type="text/css"/>
</head>
<body>
<div id="contenedor">
<div id="contenido">
<p> Establecemos conexion </p>
</div>
<div id="pie">
<p> www.railsymas.com </p>
</div>
</div>
</body>
</html:html>
resultado de la ejecución por pantalla
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 87
CÓDIGO DE LA CLASE JAVA ACCIONBASEDATOS DENTRO DEL PACKAGE DE ACCIONES
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package accion;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class accionBaseDatos extends Action {
private DataSource datasource;
private Connection conexion;
private String devolucion;
private Statement sentenciaSql;
private ResultSet resultado;
public ActionForward execute ( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response )
{
try
{
datasource = getDataSource(request);
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 88
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
conexion = datasource.getConnection();
sentenciaSql = conexion.createStatement();
resultado = sentenciaSql.executeQuery("Select * From libros");
while (resultado.next())
{
System.out.println(resultado.getString("autor"));
}
if (conexion !=null)
{
devolucion="satisfactoria";
}
conexion.close();
}
catch (SQLException e)
{
devolucion="fallida";
}
return mapping.findForward(devolucion);
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 89
61
62
63
}
}
resultado en consola de la ejecucion, los autores de la base de datos de libros_jdbc para la tabla libros
1
2
3
4
5
6
7
8
9
10
11
12
INFO: Tiles definition factory found for request processor ''.
autor1
autor2
autor3
autor4
autor5
autor6
autor7
autor7
autor8
autor9
autor10
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 90
DATASOURCE STRUTS 1.3.X PROYECTO WEB ECLIPSE
integración del enlace en la página web de ejercicios
1 2 3
<div class="enlace"> <html:link action="/datasource"> 7) datasource </html:link> </div>
CONFIGURACIÓN DE LA ACCIÓN DATASOURCE.DO EN EL STRUTS‐CONFIG.XML
1 2 3 4
<action path="/datasource" forward="/pages/formulariodatasource.jsp" />
Configuración del bean en el fichero struts‐config.xml, es la configuración del bean dinámico con las propiedades de la tabla de la base de datos libros campo titulo, temática y autor vistos en jdbc j2ee
1 2 3 4 5
<form‐bean name="beandatasource" type="org.apache.struts.validator.DynaValidatorForm"> <form‐property name="titulo" type="java.lang.String"/> <form‐property name="tematica" type="java.lang.String"/> <form‐property name="autor" type="java.lang.String"/> </form‐bean>
CONFIGURACIÓN DEL FICHERO DE PROPIEDADES
1 2 3 4 5 6 7 8 9
#datasource formulariodatasource.crear = enviar formulariodatasource.cancelar = cancelar formulariodatasource.titulo = formulario datasourceformulariodatasource.titulolibro = titulo formulariodatasource.tematica = tematica formulariodatasource.autor = autor formulariodatasource.resultado = listado de libros datasourceresultado.titulo = listado de datos
Si intentamos crear el datasource al igual que hacíamos con la versión 1.2 nos da error, en el archivo de configuración de struts
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 91
La dtd de struts 1.3 soporta un conjunto de etiquetas en el orden que se indica en la siguiente imagen.
El tag no viene soportado para esta dtd
Explicaciones del proyecto struts en el wiki datasource
Removed the and elements
creamos un package nuevo para albergar al bean libro, package vo, se llama así por el patrón value object
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
package vo; public class Libro { private String titulo; private String autor; private String tematica; public String getTitulo() { return titulo; } public void setTitulo(String titulo) { this.titulo = titulo; } public String getAutor() { return autor; } public void setAutor(String autor) { this.autor = autor; } public String getTematica() { return tematica; } public void setTematica(String tematica) { this.tematica = tematica; } }
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 92
CLASE CONEXION DENTRO DEL PACKAGE CONEXIONES
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
package conexiones; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import javax.naming.InitialContext; import javax.naming.NamingException; public class Conexion { private Connection conexion = null; public Conexion () { } public Connection establecerConexion() { try { InitialContext contexto = new InitialContext(); DataSource ds = (DataSource) contexto.lookup("java:comp/env/jdbc/datasource"); this.conexion = ds.getConnection(); } catch (NamingException e) { System.out.println(e.getMessage()); } catch (SQLException e ) { System.out.println(e.getMessage()); } return this.conexion; } }
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 93
CONFIGURACIÓN DEL FICHERO WEB.XML
1 2 3 4 5 6 7
<resource‐ref> <description>DB Connection</description> <res‐ref‐name>jdbc/datasource</res‐ref‐name> <res‐type>javax.sql.DataSource</res‐type> <res‐auth>Container</res‐auth> <res‐sharing‐scope>shareable</res‐sharing‐scope> </resource‐ref>
FICHERO CONTEXT.XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
<?xml version="1.0" encoding="UTF‐8"?><Context path="/DBTest" docBase="DBTest" debug="5" reloadable="true" crossContext="true"> <!‐‐ maxActive: Maximum number of dB connections in pool. Make sure you configure your mysqld max_connections large enough to handle all of your db connections. Set to ‐1 for no limit. ‐‐> <!‐‐ maxIdle: Maximum number of idle dB connections to retain in pool. Set to ‐1 for no limit. See also the DBCP documentation on this and the minEvictableIdleTimeMillis configuration parameter. ‐‐> <!‐‐ maxWait: Maximum time to wait for a dB connection to become available in ms, in this example 10 seconds. An Exception is thrown if this timeout is exceeded. Set to ‐1 to wait indefinitely. ‐‐> <!‐‐ username and password: MySQL dB username and password for dB connections ‐‐> <!‐‐ driverClassName: Class name for the old mm.mysql JDBC driver is org.gjt.mm.mysql.Driver ‐ we recommend using Connector/J though. Class name for the official MySQL Connector/J driver is com.mysql.jdbc.Driver. ‐‐> <!‐‐ url: The JDBC connection url for connecting to your MySQL dB. ‐‐> <Resource name="jdbc/datasource" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="root" password="root" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/libros_jdbc"/> </Context>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 94
CONFIGURACIÓN DE LA ACCIÓN FORMULARIODATASOURCE.DO
1 2 3 4 5 6 7 8 9 10 11 12 13
<action path="/formulariodatasource" type="acciones.ConexionDatasource" scope="request" validate="true" name="beandatasource" input="/pages/formulariodatasource.jsp"> <set‐property property="cancellable" value="true" /> <forward name="cancelada" path="/pages/cancelada2.jsp"></forward> <forward name="mostrardatos" path="/pages/mostrarlistado.jsp"> </forward> </action>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
package acciones; import conexiones.Conexion; import vo.Libro; import java.io.PrintWriter; import java.sql.SQLException; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionForm; import org.apache.struts.validator.DynaValidatorForm; import java.sql.Statement; import java.sql.Connection; import java.sql.ResultSet; import java.util.ArrayList; import javax.servlet.http.HttpSession; public class ConexionDatasource extends Action { private Connection conexionr = null; private ActionForward envio = null; private Conexion conexion = null; private Statement sentenciaSql; private ResultSet resultado = null; private Libro libro; private ArrayList<Libro> listalibros; private HttpSession session = null; public ActionForward execute (ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { DynaValidatorForm formulario = (DynaValidatorForm)form; conexion = new Conexion(); response.setContentType("Text/html");
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 95
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
PrintWriter salida = response.getWriter(); if (this.isCancelled(request)) { envio = mapping.findForward("cancelada"); } else { try { conexionr = conexion.establecerConexion(); sentenciaSql = conexionr.createStatement(); //ejecutamos la sentencia de selección de los campos menos el id System.out.print(formulario.get("titulo")); System.out.print(formulario.get("autor")); System.out.print(formulario.get("tematica")); sentenciaSql.executeUpdate(" INSERT INTO libros VALUES ("+0+",'"+formulario.get("titulo")+"','"+formulario.get("autor")+"','"+formulario.get("tematica")+"');"); //recuperamos los datos de la base de datos resultado = sentenciaSql.executeQuery("SELECT * from libros;"); if ( resultado != null) { //creamos el array de libros listalibros = new ArrayList<Libro>(); while (resultado.next()) { libro = new Libro(); libro.setTitulo(resultado.getString("titulo")); libro.setAutor(resultado.getString("autor")); libro.setTematica(resultado.getString("tematica")); listalibros.add(libro); } //cerramos la conexion conexionr.close(); //establecemos el parámetro por peticion session = request.getSession(true); session.setAttribute("listadolibros", listalibros); envio = mapping.findForward("mostrardatos");
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 96
99 100 101 102 103 104 105 106 107 108 109 110 111 112
} } catch( SQLException e ) { salida.println("Excepcion Sql : "+ e.getMessage()); } } return envio; } }
FORMULARIODATASOURCE.JSP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%> <%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <html:base/> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <link rel="stylesheet" type="text/css" href="../css/estilo.css" /> <title><bean:message key="formulariodatasource.titulo"/></title> </head> <body> <div id="contenedor"> <h2><bean:message key="formulariodatasource.titulo"/></h2> <div id="errores"> <html:errors/> </div> <div id="imagen"> <html:img srcKey="dinamico.registro.imagen" titleKey="dinamico.registro.imagen.alt"/> </div> <div id="contenido"> <html:form action="formulariodatasource" focus="nombre" styleId="formulario" method="post"> <div class="campo"> <bean:message key="formulariodatasource.titulolibro"/> <html:text property="titulo"/> </div> <div class="campo"> <bean:message key="formulariodatasource.autor"/> <html:text property="autor"/> </div> <div class="campo"> <bean:message key="formulariodatasource.tematica" /> <html:text property="tematica"/>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 97
38 39 40 41 42 43 44 45 46 47 48 49
</div> <html:submit styleClass="boton"> <bean:message key="formulariodatasource.crear"/> </html:submit> <html:cancel styleClass="boton"> <bean:message key="formulariodatasource.cancelar"/> </html:cancel> <html:reset styleClass="boton"> borrar</html:reset> </html:form> </div> <div id="pie"> <p> www.railsymas.com </p> </div> </div> </body> </html:html>
Imagen correspondiente
MOSTRARLISTADO.JSP
Las etiquetas logic nos permiten iterar sobre los resultados obtenidos, logic:empty nos permite saber si el valor de la variable referenciada por name está vacío, en éste caso se utiliza para mostrar el mensaje correspondiente. Para comprobar que no está vacío se utiliza logic:notEmpty, para luego iterar por los resultado con logic:iterate
1 2 3 4 5 6 7 8 9 10 11 12
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <%@taglib uri="http://struts.apache.org/tags‐logic" prefix="logic"%> <%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <html:base/> <title><bean:message key="datasourceresultado.titulo"/></title>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 98
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
<link rel="stylesheet" href="../css/estilo.css" type="text/css"/> </head> <body> <div id="contenedor"> <div id="tabla"> <logic:empty name="listadolibros"> <p> La base de datos de libros esta vacía </p> </logic:empty> <logic:notEmpty name="listadolibros"> <h2><bean:message key="formulariodatasource.resultado"/></h2> <table title="tabla de datos libros"> <tr><th> titulo </th> <th> autor </th> <th> tematica </th></tr> <logic:iterate name="listadolibros" id="libro"> <tr> <td class="par"> <bean:write name="libro" property="titulo"/> </td> <td class="impar"> <bean:write name="libro" property="autor"/> </td> <td class="par"> <bean:write name="libro" property="tematica"/> </td> </tr> </logic:iterate> </table> </logic:notEmpty> </div> <div id="pie"> <p> www.railsymas.com </p> </div> </div> </body> </html>
Imagen correspondiente
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 99
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 100
MOSTRANDO LISTADO DE DATOS
Cuando mostramos los datos, recogidos de una bases de datos, puede que el número de items recogidos sea bastante amplio por lo que resultaría bastante engorroso para el usuario ver un listado muy largo.
Se hace necesario dar una respuesta a este problema. para ello utlizamos la paginación
Podemos crear de dos formas distintas, bien a mano o bien utilizando una librería de struts adecuada. Displaytag es un jar que permite la paginación y la exprotación de datos a diferentes formatos.
Para su utilización, necesitamos importar la librería display tag ( http://displaytag.sf.net)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%><%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <%@taglib uri="http://displaytag.sf.net" prefix="display" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <html:base/> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title><bean:message key="displaytag.titulo"/></title> <link rel="stylesheet" type="text/css" href="../css/estilo.css"/> </head> <body> <div id="contenedor"> <div id="tabla"> <display:table id="libro" name="sessionScope.listadolibros" pagesize="5" requestURI="/mostrarlistadodisplaytag.do"> <display:column property="titulo" title="título" sortable="true"/> <display:column property="autor" title="autor" sortable="true"/> <display:column property="tematica" title="temática" sortable="true"/> </display:table> </div> <div id="pie"> <p> www.railsymas.com </p> </div> </div> </body> </html:html>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 101
necesitamos incorporar el archivo de propiedades, para displaytag,
Los datos que se muestran pueden cambiar, dejar menos es posible
al pasar la página
en la carpeta src se copia el fichero de propiedades en
castellano
_es_zona geográfica ejemplo es_AR, es_MX etc ….
el action al que llama la tabla en su atributo uri, configurado en el struts‐config.xml
1 2 3
<action path="/mostrarlistadodisplaytag" forward="/pages/mostrarlistadodisplaytag.jsp"/>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 102
DESARROLLO WEB UPLOADFILE STRUTS
Ejemplo para subir un archivo zip mediante struts
form bean, se declara el nombre del formulario bean como uploadForm en atributo type se declara la ruta de la clase bean
1 2 3
<!‐‐ el formbean solamente necesita el name y el type ‐‐> <form‐bean name="uploadForm" type="formularios.Formularioupload"/>
En el archivo de configuración del struts‐config.xml en la seccion de actions mediante el atributo path indicamos que struts responda ante una acción uploadfile con la página ubicada en /pages/formularioloadfile.jsp en cargada de mostrar un formulario para subir el archivo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<action path="/uploadfile" forward="/pages/formulariouploadfile.jsp"> </action> <action path="/subirarchivo" type="acciones.SubirArchivo" scope="request" name="uploadForm" validate="true" input="/pages/formulariouploadfile.jsp"> <forward name="subido" path="/pages/mostrarInformacion.jsp"/> </action>
Si se subió el archivo web correctamente se realiza un reenvio a la página mostrarinformación para indicar un mensaje de confirmación al usuario, en caso
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 103
contrario mediante el atributo input se indica que la propia página jsp de subida del archivo muestre por pantalla el mensaje correspondiente según el error cometido
CÓDIGO DE LA CLASE SUBIR ARCHIVO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
package acciones; import org.apache.struts.action.Action; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.upload.FormFile; import formularios.Formularioupload; import java.io.FileOutputStream; import java.io.File; public class SubirArchivo extends Action { private ActionForward envio; public ActionForward execute (ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { Formularioupload formularioSubido = (Formularioupload) form; FileOutputStream fileoutputstream = null; try { FormFile fichero = formularioSubido.getFichero(); String ruta = this.getServlet().getServletContext().getRealPath("/upload/")+fichero.getFileName(); fileoutputstream = new FileOutputStream(new File(ruta)); fileoutputstream.write(fichero.getFileData()); } finally { if(fileoutputstream !=null) { fileoutputstream.close(); } } return mapping.findForward("subido"); } }
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 104
CÓDIGO DE LA PÁGINA JSP ENCARGADA DE MOSTRAR EL FORMULARIO DE SUBIDA DE ARCHIVO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html"%> <%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <html:base/> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title><bean:message key="uploadfile.titulo"/></title> <link rel="stylesheet" type="text/css" href="../css/estilo.css" /> </head> <body> <div id="contenedor"> <h2><bean:message key="uploadfile.titulo"/> </h2> <div id="errores"> <html:errors/> </div> <div id="contenido"> <div id="imagen"> <html:img srcKey="uploadfile.imagen" altKey="uploadfile.imagen.alt"/> </div> <html:form method="post" action="/subirarchivo" enctype="multipart/form‐data"> <div id="campo"> <bean:message key="uploadfile.fichero"/> <html:file property="fichero"/> <br/> <html:submit styleClass="boton" value="enviar"/> </div> </html:form> </div> <div id="pie"> <p> www.railsymas.com </p> </div> </div> </body> </html:html>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 105
EN EL FICHERO DE PROPIEDADES
1 2 3 4 5 6 7 8 9
#uploadfile uploadfile.titulo = formulario uploadfile uploadfile.fichero = introduce el fichero a subir uploadfile.imagen = ../imagenes/subirarchivo.png uploadfile.imagen.alt = imagen archivo error.fichero.vacio = el fichero esta vacío error.fichero.tipo = el archivo no es de tipo zip error.fichero.tamanio = error el tamaño excede lo permitidouploadfile.resultado = formulario subido
CLASE BEAN PARA EL FORMULARIO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
package formularios; import org.apache.struts.action.ActionForm; import org.apache.struts.upload.FormFile; import org.apache.struts.action.ActionErrors; import javax.servlet.http.HttpServletRequest; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionMessage; public class Formularioupload extends ActionForm { static final long serialVersionUID = 1L; private FormFile fichero; private String informacion; public String getInformacion() { return informacion; } public void setInformacion(String informacion) { this.informacion = informacion; } public FormFile getFichero() { return fichero; } public void setFichero(FormFile fichero) { this.fichero = fichero; } public ActionErrors validate (ActionMapping mapping, HttpServletRequest request) { ActionErrors errores = new ActionErrors (); //ya esta subido miramos si es del tipo indicado if (fichero.getFileSize() == 0) { //esta vacío errores.add("fichero", new ActionMessage ("error.fichero.vacio"));
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 106
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
} else { if ( !fichero.getContentType().equals("application/x‐zip‐compressed")) { errores.add("fichero",new ActionMessage("error.fichero.tipo")); System.out.print(fichero.getContentType()); } else { if ( fichero.getFileSize() > 2000000 ) { errores.add("fichero", new ActionMessage("error.fichero.tamanio")); } } } return errores; } }
Situación en la que hemos dado al botón de enviar sin haber seleccionado un archivo
Error de formato de archivo
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 107
Situación el archivo, sí tiene el formato zip pero nos hemos excedido de tamaño soportado por la aplicación
Situación en la que hemos enviado correctamente el archivo
Para comprobar el fichero subido al proyecto desplegamos la aplicación en el servidor tomcat mediante un war del proyecto
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 108
DESARROLLO WEB MÚLTIPLES ARCHIVOS DE CONFIGURACIÓN STRUTS
En este post veremos como crear diferentes archivos de configuración para el framework struts.
Estamos con la versión 1.3.10 de struts y se llevan mostrados diferentes ejemplos sobre este framework. siempre a la hora de activar un componente de struts teníamos que ir al archivo de configuración, llega el momento en que este archivo de configuración esta sobrecargado de líneas de código.
En este ejemplo intervienen los dos archivos de configuración, declaración de una acción en el archivo de configuración de struts‐config.xml denominada “multiconfiguración” y se produce el reenvio a la página enlaceprivado.jsp
1 2 3
<action path="/multiconfiguracion" forward="/pages/enlaceprivado.jsp"/>
CÓDIGO DE LA PÁGINA ENLACEPRIVADO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <html:base/> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title><bean:message key="enlaceprivado.titulo"/> </title> <link rel="stylesheet" type="text/css" href="../css/estilo.css"/> </head> <body> <div id="contenedor"> <div id="contenido"> <div id="campo"> <html:link action="/config2"> Zona privada </html:link> </div> </div> <div id="pie"> <p>www.railsymas.com </p> </div> </div>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 109
26 </body> </html:html>
En esa página jsp existe un enlace que activa la acción config2 que aparece en el fichero de configuración struts‐config2.xml
Enlace imagen
Se declara en struts‐config2.xml un bean dinámico llamado formularioprivado con dos campos de tipo string, y una acción privado, que va ser tratada desde struts‐config2.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
<form‐beans> <form‐bean name="formularioprivado" type="org.apache.struts.validator.DynaValidatorForm"> <form‐property name="usuario" type="java.lang.String"/> <form‐property name="clave" type="java.lang.String"/> </form‐bean> </form‐beans> <action‐mappings> <action path ="/config2" forward ="/pages/privado.jsp" /> <action path="/privado" type="acciones.Privado" name="formularioprivado" input="/pages/privado.jsp" validate="true" > <forward name="satisfactorio" path="/pages/satisfactorio.jsp"/> <forward name="error" path="/pages/cancelada2.jsp"/> </action>
visualización de la página privado donde se muestra un formulario de usuario,
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 110
EN EL FICHERO WEB.XML DEL PROYECTO
1 2 3 4 5 6 7 8 9 10
<!‐‐ Standard Action Servlet Configuration ‐‐> <servlet> <servlet‐name>action</servlet‐name> <servlet‐class>org.apache.struts.action.ActionServlet</servlet‐class> <init‐param> <param‐name>config</param‐name> <param‐value>/WEB‐INF/struts‐config.xml , /WEB‐INF/struts‐config2.xml </param‐value> </init‐param> <load‐on‐startup>2</load‐on‐startup> </servlet>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 111
DESARROLLO WEB COMODINES STRUTS
Seguimos con el tutorial de struts
Página jsp con varios ejemplos de utilización de comodines (wildcard)
Creamos un fichero de configuración struts específico para el ejemplo y lo integramos en el fichero descriptor de despliegue en struts‐configWildcard.xml
1 2 3 4 5 6 7 8 9 10
<!‐‐ Standard Action Servlet Configuration ‐‐> <servlet> <servlet‐name>action</servlet‐name> <servlet‐class>org.apache.struts.action.ActionServlet</servlet‐class> <init‐param> <param‐name>config</param‐name> <param‐value>/WEB‐INF/struts‐config.xml , /WEB‐INF/struts‐config2.xml , /WEB‐INF/struts‐configWildcard.xml </param‐value> </init‐param> <load‐on‐startup>2</load‐on‐startup> </servlet>
CONFIGURACIÓN DEL ARCHIVO STRUTS‐CONFIGWILDCARD.XML
1 2 3 4 5 6 7 8 9 10 11
struts‐config> <!‐‐ se puede aplicar a los ‐‐> <action‐mappings> <action path="/enlaces" forward="/pages/enlaces.jsp"/> <action path="/Primero*" forward="/pages/Wildcard/Paginap1.jsp"/> <action path="/*segundo" forward="/pages/Wildcard/{1}.jsp"/> </action‐mappings> </struts‐config>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 112
CÓDIGO DE ENLACES.JSP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%><%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <title><bean:message key="wildcard.enlace.titulo"/> </title> <html:base/> <link rel="stylesheet" href="../css/estilo.css" type="text/css"/> </head> <body> <div id="contenedor"> <h2> Enlaces </h2> <div id="contenido"> <div id="campo"> <html:link action="PrimeroPaginap1"> primero página p1</html:link> </div> <div id="campo"> <html:link action="Paginap1segundo"> página p1 segundo </html:link> </div> <div id="campo"> <html:link action="Paginap2segundo"> primera página p2 </html:link> </div> </div> <div id="pie"> <p> www.railsymas.com </p> </div> </div> </body> </html>
Las páginas jsp son simples, no tienen ningun código especial
PÁGINA 1 JSP
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 113
PÁGINA 2 JSP
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 114
CREACIÓN DE UN PLUGIN CON STRUTS XML DOM
Tutorial de struts para la creación de un plugin en struts
Struts nos permite la creación de plugins propios, en los diferentes post utilizabamos plugins standard como struts‐validator y struts‐tiles. Pero también se pueden crear plugins a medida de nuestras necesidades
Tenemos un fichero xml, donde tenemos una estructura un elemento nodo raiz llamado plantilla y una serie de nodos hijos llamados obrero, cada elemento hijo consta de un atributo nombre y dos elementos subhijos cargo y edad
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<?xml version="1.0" encoding="UTF‐8"?><plantilla> <obrero nombre="pepe"> <cargo>peón</cargo> <edad>25</edad> </obrero> <obrero nombre="juan"> <cargo>capataz</cargo> <edad>46</edad> </obrero> <obrero nombre="maria"> <cargo>pintor</cargo> <edad>38</edad> </obrero> </plantilla>
Este fichero xml lo denominamos plantillas.xml y será el fichero que lea el plugin de struts.
Para la creación del plugin debemos de declararlo en el fichero struts‐config.xml
1 2 3 4 5 6 7
<!‐‐ =============================================== Plug Ins Configuration ‐‐> <plug‐in className="acciones.PluginEjemplo"> <set‐property property="direccion" value="/WEB‐INF/plantilla.xml"/> </plug‐in>
Por un lado tenemos el nombre el de la clase del plugin, en el valor del atributo className y por otro el valor de la propiedad dirección en el que indicamos la ruta a la dirección del fichero xml
La clase que implementa la interface Plugin, debe implementar los métodos init y destroy, si se pasan parámetros en la declaración del plugin en este caso dirección con el valor de la ruta al fichero para poder asignar valor y recuperar desde la clase del plugin es necesario crear métodos getter y setter
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 115
El resto de los métodos son los encargados de leer el fichero xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
package acciones; import java.io.File; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import org.apache.struts.action.PlugIn; import org.apache.struts.action.ActionServlet; import org.apache.struts.config.ModuleConfig; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.ParserConfigurationException; import vo.Obrero; import java.util.ArrayList; public class PluginEjemplo implements PlugIn { private static final String nombreclase = PluginEjemplo.class.getName(); private String direccion; private Document documento; private static ArrayList<Obrero> listadoObreros = new ArrayList<Obrero>(); public String getDireccion() { return direccion; } public void setDireccion(String direccion) { this.direccion = direccion; } public void init (ActionServlet servlet, ModuleConfig config) throws ServletException { ServletContext contexto = servlet.getServletContext(); System.out.println(nombreclase+"direccion:"+getDireccion());
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 116
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
PluginEjemplo pluginejemplo = new PluginEjemplo(); leerXml (getDireccion(),servlet); contexto.setAttribute(nombreclase,pluginejemplo ); } public void leerXml(String direccion, ActionServlet servlet) { DocumentBuilderFactory factoria = DocumentBuilderFactory.newInstance(); try { DocumentBuilder constructor = factoria.newDocumentBuilder(); ServletContext contexto = servlet.getServletContext(); String lugar = contexto.getRealPath(direccion); documento = constructor.parse(new File(lugar)); documento.getDocumentElement().normalize(); Node nodoraiz = documento.getDocumentElement(); new ArrayList<Obrero>(); System.out.println(nodoraiz.getNodeName()); nodos(documento); } catch (ParserConfigurationException ex) { System.out.println("no se puede crear el Dom parser:"+ex); } catch (SAXException ex) { System.out.print("Generar Sax excepción: "+ex); } catch (IOException ex) { System.out.print("Io excepción: "+ex); } } private void nodos (Document documento) { NodeList listadenodos = documento.getElementsByTagName("obrero");
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 117
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
for (int i= 0; i < listadenodos.getLength() ; i++) { Node nodo = listadenodos.item(i); Obrero obrero = new Obrero(); if (nodo.getNodeType() == Node.ELEMENT_NODE) { Element elemento = (Element) nodo; obrero.setNombre(elemento.getAttribute("nombre")); obrero.setCargo(getValor("cargo",elemento)); obrero.setEdad(Integer.parseInt(getValor("edad",elemento))); } listadoObreros.add(obrero); } } private String getValor (String cadenatag, Element elemento) { NodeList listado = elemento.getElementsByTagName(cadenatag).item(0).getChildNodes(); Node nodo = listado.item(0); return nodo.getNodeValue(); } public static ArrayList<Obrero> getListado() { return listadoObreros; } public void destroy () { System.out.println("Fin del plugin"); } }
CLASE OBRERO
1 2 3 4 5 6 7 8 9
package vo; public class Obrero { private String nombre; private int edad; private String cargo; public String getNombre() {
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 118
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public int getEdad() { return edad; } public void setEdad(int edad) { this.edad = edad; } public String getCargo() { return cargo; } public void setCargo(String cargo) { this.cargo = cargo; } }
CONFIGURACIÓN DEL ACTION EN STRUTS‐CONFIG.XML
1 2 3 4 5 6 7 8 9 10
<action path="/crearplugin" type="acciones.AccionRecogerObreros"> <forward name="satisfactorio" path="/pages/listadoobreros.jsp" /> </action>
Resultado final
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 119
INTEGRACIÓN STRUTS HIBERNATE
En este ejemplo se inserta un tupla en la base de datos creada, con los datos introducidos mediante un formulario rellenado por el usuario
Tenemos la tabla libros de la base de datos libros_jdbc, tal como viene en este ejemplo base de datos. Tenemos una tabla libros pertenecientes a la base datos con tres campos el titulo, autor y la temática del libro.
Para este ejemplo necesitamos para un mejor entendimiento necesitamos conocer como se crea un plugin y aquí tenemos uno hecho creación de plugin
Formulario de recogida de datos
este formumario esta asociado a una acción recogida en el fichero de configuración de struts el struts‐config.xml
1 2 3 4 5 6 7 8 9 10 11 12 13
<action path="/formularioHibernate" type="acciones.AccionHibernateLibro" scope="request" name="hibernatelibro" validate="true" input="/pages/formulariohibernate.jsp" > <set‐property property="cancellable" value="true" /> <forward name="listado" path="/pages/listadohibernate.jsp"/> <forward name="cancelada" path="/pages/cancelada2.jsp"/> </action>
Se ha explicado en otros post anteriores cada uno de los elementos que aparecen en esta configuración, pero a modo de recordatorio, se enumeran los valores de los diferentes campos. Para el path tenemos el nombre de la acción que se ejecuta en este
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 120
caso (formulariohibernate), esta acción esta recogida en una clase (AccionHibernateLibro) que es la encargada de evaluar y procesar los datos, el name hace referencia al bean en este caso dinámico encargado de recoger los datos del formulario (hibernatelibro).
Código del bean dinámico encargado de recoger los datos del formulario, para poder ser tratados por la clase (AcciónHibernateLibro)
1 2 3 4 5
<form‐bean name="hibernatelibro" type="org.apache.struts.validator.DynaValidatorForm"> <form‐property name="titulo" type="java.lang.String"/> <form‐property name="tematica" type="java.lang.String"/> <form‐property name="autor" type="java.lang.String"/> </form‐bean>
Código del formulario formulariohibernate.jsp correspondiente a la imagen anterior
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
<%@ page language="java" contentType="text/html; charset=UTF‐8" pageEncoding="UTF‐8"%> <%@taglib uri="http://struts.apache.org/tags‐html" prefix="html" %> <%@taglib uri="http://struts.apache.org/tags‐bean" prefix="bean" %> <!DOCTYPE html PUBLIC "‐//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <html:base/> <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8"> <link rel="stylesheet" href="../css/estilo.css" type="text/css"/> <title><bean:message key="titulo.hibernate"/></title> </head> <body> <div id="contenedor"> <h2><bean:message key="titulo.hibernate"/></h2> <div id="errores"> <html:errors/> </div> <div id="imagen"> <html:img srcKey="libro.imagen" titleKey="libro.imagen.alt"/> </div> <div id="contenido"> <html:form method="post" action="formularioHibernate" styleId="formulario" focus="titulo" > <div class="campo"> <bean:message key="formulariodatasource.titulolibro"/> <html:text property="titulo"/> </div> <div class="campo"> <bean:message key="formulariodatasource.autor"/>
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 121
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
<html:text property="autor"/> </div> <div class="campo"> <bean:message key="formulariodatasource.tematica"/> <html:text property="tematica"/> </div> <html:submit styleClass="boton" value="enviar"/> <html:cancel styleClass="boton" value="cancelar"/> <html:reset styleClass="boton" value="borrar"/> </html:form> </div> <div id="pie"> <p> www.railsymas.com </p> </div> </div> </body> </html:html>
configuración del plugin en el fichero struts‐config.xml, creamos un plugin indicando la clase HibernatePlugin y la propiedad dirección con el valor de la ruta del fichero de configuración de hibernate
1 2 3 4 5 6 7 8
<!‐‐ ========== Hibernate ======= ‐‐> <plug‐in className="configuracion.plugin.HibernatePlugin"> <set‐property property="direccion" value="/hibernate.cfg.xml"/> </plug‐in>
para cargar el fichero de configuración de hibernate creamos un plugin, como repaso tenemos que extender de la clase Plugin y sobre escribimos los métodos destroy e init. Se crea por comodidad una variable estática de la clase llamada clave_hibernate que nos permitirá recoger la factoria de hibernate para poder insertar, borrar, editar etc..
1 2 3 4 5 6
package configuracion.plugin; import javax.servlet.ServletContext; import javax.servlet.ServletException; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration;
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 122
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
import org.apache.struts.action.ActionServlet;import org.apache.struts.action.PlugIn; import org.apache.struts.config.ModuleConfig; import org.hibernate.HibernateException; public class HibernatePlugin implements PlugIn { private String direccion; public static final String clave_hibernate = "Hibernate"; private SessionFactory factoria = null; public String getDireccion() { return direccion; } public void setDireccion(String direccion) { this.direccion = direccion; } public void destroy() { try { factoria.close(); } catch(HibernateException e) { System.out.println("No se puede cerrar la sesión: " + e.getMessage()); } } public void init(ActionServlet servlet, ModuleConfig config) throws ServletException { Configuration configuration = null; ServletContext contexto = null; try{ contexto = servlet.getServletContext(); configuration = (new Configuration()).configure(direccion); factoria = configuration.buildSessionFactory(); contexto.setAttribute(clave_hibernate, factoria); }catch(HibernateException e){ System.out.println("Error de inicialización de hibernate: " + e.getMessage()); }
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 123
63 64 65 66 67 68
} }
código de la clase encargada de recoger la acción, esta clase como solamente realiza una acción extendemos de action y editamos el método ejecute. Esta clase es la encargada de recoger los datos del formulario así como de la utilización de recuperar el manejador de la factoria.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
package acciones; import org.apache.struts.action.Action; import org.apache.struts.action.ActionMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletContext; import org.apache.struts.action.ActionForm; import org.apache.struts.validator.DynaValidatorForm; import org.apache.struts.action.ActionForward; import configuracion.plugin.HibernatePlugin; import org.hibernate.SessionFactory; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.TransactionException; import modelos.*; import java.util.List; import java.util.Iterator; public class AccionHibernateLibro extends Action { private ActionForward reenvio = null; private DynaValidatorForm formulario = null; private Session sesion = null; private SessionFactory factory= null; private Transaction transaction = null; public ActionForward execute (ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { formulario = (DynaValidatorForm) form; if (isCancelled(request))
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 124
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
{ reenvio = mapping.findForward("cancelada"); } else { ServletContext context = request.getSession().getServletContext(); factory = (SessionFactory) context.getAttribute(HibernatePlugin.clave_hibernate); sesion = factory.openSession(); try { transaction = sesion.beginTransaction(); Libros libro = new Libros(); //introducimos los valores para el libro nuevo libro.setTitulo(formulario.getString("titulo")); libro.setAutor(formulario.getString("autor")); libro.setTematica(formulario.getString("tematica")); sesion.save(libro); transaction.commit(); transaction = sesion.beginTransaction(); List <Libros> libros = sesion.createQuery("from Libros").list(); for ( Iterator <Libros> iterador = libros.iterator() ; iterador.hasNext();) { libro = (Libros) iterador.next(); System.out.println("titulo:"+libro.getTitulo()); System.out.println("autor:"+libro.getAutor()); System.out.println("tematica:"+libro.getTematica()); } transaction.commit(); request.setAttribute("libros", libros); reenvio = mapping.findForward("listado"); } catch (TransactionException e ) {
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 125
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
//abortamos la transacción y restauramos los valores anteriores transaction.rollback(); e.printStackTrace(); } finally { //cerramos la sesión sesion.close(); } } return reenvio; } }
ARCHIVO DE CONFIGURACIÓN HIBERNATE.CFG,XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
<?xml version="1.0" encoding="UTF‐8"?><!DOCTYPE hibernate‐configuration PUBLIC "‐//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate‐configuration‐3.0.dtd"> <hibernate‐configuration> <session‐factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <property name="hibernate.connection.url"> jdbc:mysql://localhost:3306/libros_jdbc</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property> <property name="hibernate.hbm2ddl.auto">update</property> <property name="show_sql">true</property> <property name="format_sql">true</property> <mapping resource="modelos/Libros.hbm.xml"/> </session‐factory> </hibernate‐configuration>
sobre los parámetros recogidos en el fichero hibernate.cfg.xml se comentaron en el post hibernate tools
Para el mapeo de las tablas tenemos que crear un archivo xml con extension hbm.xml. estos archivos los podemos poner en un package propio por en este ejemplo “modelo” haciendo referencia a las las clases y ficheros de configuración asociados a las tablas de la base de datos.
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 126
Al ejecutar la aplicación se nos crea automáticamente una clase bean con los propiedades indicadas en los ficheros hbm.xml, en este caso una clase Libro
Para crear un fichero hbm vamos con la vista hibernate de eclipse activada a new, hibernate xml mapping creamos un fichero libros.hbm.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
<?xml version="1.0"?> <!DOCTYPE hibernate‐mapping PUBLIC "‐//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate‐mapping‐3.0.dtd"> <!‐‐ Generated 26‐ene‐2010 1:33:06 by Hibernate Tools 3.2.4.GA ‐‐> <hibernate‐mapping> <class name="modelos.Libros" table="libros" catalog="libros_jdbc"> <id name="id" type="java.lang.Integer"> <column name="id" /> <generator class="identity" /> </id> <property name="titulo" type="string"> <column name="titulo" length="50" not‐null="true" /> </property> <property name="autor" type="string"> <column name="autor" length="50" not‐null="true" /> </property> <property name="tematica" type="string"> <column name="tematica" length="50" not‐null="true" /> </property> </class> </hibernate‐mapping>
Valores de los parámetros, table hace referencia a la tabla de la base de datos, catalog hace referencia a la base de datos, el primer parametro id indicamos que el campo es la clave primaria, los atributos property indicamos el nombre de la propiedad y a que campo de la tabla corresponde es decir podemos tener el campo titulo en la tabla y en la propiedad titu_x por decir algo, entoces a la hora de usar por código el objeto de mapeo haríamos objeto.titu_x pero por comodidad le damos el mismo valor que la tabla así es más fácil acordorse de las propiedades.
Imagen del listado del libro una vez guardado los datos
TUTORIAL FRAMEWORK STRUTS
http://www.railsymas.com 127
Salida por pantalla para verificar la inserción como consecuencia de activar en el fichero hibernate.cfg.xml el parámetro show_sql y format_sql
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
INFO: Tiles definition factory found for request processor ''.Hibernate: insert into libros_jdbc.libros (titulo, autor, tematica) values (?, ?, ?) Hibernate: select libros0_.id as id0_, libros0_.titulo as titulo0_, libros0_.autor as autor0_, libros0_.tematica as tematica0_ from libros_jdbc.libros libros0_ titulo:titulo3 autor:autor3 tematica:tematica3