Vous êtes sur la page 1sur 18

Introduccin a Struts

Es un framework que implementa el patrn de arquitectura MVC en Java Un framework es la extensin de un lenguaje mediante una o ms jerarquas de clases que implementan una funcionalidad y que (opcionalmente) pueden ser extendidas. El framework puede involucrar TagLibraries. El patrn de arquitectura MVC (Model-View-Controller) es un patrn que define la organizacin independiente del Model (Objetos de Negocio), la View (interfaz con el usuario u otro sistema) y el Controller (controlador del workflow de la aplicacin: "si estoy aqu y me piden esto entonces hacer tal cosa, si sale bien mostrar esto y sino lo aquello otro").

Cmo funciona Struts?

El navegador genera una solicitud que es atendida por el Controller (un Servlet especializado). El mismo se encarga de analizar la solicitud, seguir la configuracin que se le ha programado en su XML y llamar al Action correspondiente pasndole los parmetros enviados. El Action instanciar y/o utilizar los objetos de negocio para concretar la tarea. Segn el resultado que retorne el Action, el Controller derivar la generacin de interfaz a una o ms JSPs, las cuales podrn consultar los objetos del Model a fines de realizar su tarea.

Para qu sirve Struts?

Evidentemente, como todo framework intenta, simplifica notablemente la implementacin de una arquitectura segn el patrn MVC. El mismo separa muy bien lo que es la gestin del workflow de la aplicacin, del modelo de objetos de negocio y de la generacin de interfaz. El controlador ya se encuentra implementado por Struts, aunque si fuera necesario se puede heredar y ampliar o modificar, y el workflow de la aplicacin se puede programar desde un archivo XML Las acciones que se ejecutarn sobre el modelo de objetos de negocio se implementan basndose en clases predefinidas por el framework y siguiendo el patrn Facade. Y la generacin de interfaz se soporta mediante un conjunto de Tags predefinidos por Struts cuyo objetivo es evitar el uso de Scriplets (los trozos de cdigo Java entre "<%" y "%>"), lo cual genera ventajas de mantenibilidad y de perfomance (pooling de Tags, caching, etc). Logsticamente, separa claramente el desarrollo de interfaz del workflow y lgica de negocio permitiendo desarrollar ambas en paralelo o con personal especializado. Tambin es evidente que potencia la reutilizacin, soporte de mltiples interfaces de usuario (Html, sHtml, Wml, Desktop applications, etc.) y de mltiples idiomas, localismos, etc.

Ejemplo cdigo Struts


Contenid o:
- Introduccin - struts-config.xml - ActionForm - FormBean - JSP - DAO

Introduccin:
En este apartado veremos la representacin en cdigo de un proyecto web con struts y servidor Tomcat 5.5. Trataremos el tipo de parametros que se codifican en el struts-xml para definir la navegacin web de la aplicacin as como la relacin ActionForm-FormBean, las JSPs que contendrn la informacin que enviaremos a los ActionForm-FormBean y de ahi a las BD y viceversa.

struts-config.xml
Podemos encontrar este fichero tras dentro de nuestro proyecto tras desplegar "Web Pages" dentro del directorio "WEB-INF". Su contenido podra ser similar a esto: <struts-config> <form-beans> <form-bean name="consultaUsuariosForm" type="com.jao.controladores.consultas.forms.consultaUsuariosForm"/> .... .... </form-beans> <action-mappings> <action path="/consultaUsuariosAction" type="com.jao.controladores.consultas.actions.consultaUsuariosAction" name= "consultaUsuariosForm" scope="request" validate="false" >

<forward name="success" path="JSPs/rsConsultaUsuarios.jsp" /> <forward name="error" path="JSPs/formulario.jsp" /> </action> <action path="/altaUsuariosAction" type="com.jao.controladores.consultas.actions.altaUsuariosAction" name="consultaUsuariosForm" scope="request" validate="false" > <forward name="success" path="JSPs/altaExito.jsp" /> <forward name="error" path="JSPs/erroralta.jsp" /> </action> ...... ...... </action>

Action Form
package com.jao.controladores.consultas.actions; import com.jao.controladores.consultas.forms.consultaUsuariosForm; import com.jao.dao.usuarioDao; import java.util.ArrayList;

DAO
El ejemplo completo del DAO usuarioDAO.java se puede ver en el apartado J2EE->JDBC package com.jao.dao; import com.jao.controladores.consultas.forms.consultaUsuariosForm; import com.jao.controladores.forms.login; import com.jao.model.Usuario; import java.sql.Statement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.ResultSet; import java.util.ArrayList; /** * * @author JAO */ public class usuarioDao { public int insert( consultaUsuariosForm usu ) throws SQLException { int numFilas = 0; Statement sentencia=null; Connection con=null; try { con = getConexion(); String strSQL = "INSERT INTO usuarios VALUES (" + "'"+usu.getUsuario()+"','" + usu.getClave()+ "','"+ usu.getEdad()+"','" + usu.getFechanacimiento() + "',"+ "'" + usu.getProfesion()+ "',null)"; sentencia = (Statement) con.createStatement(); numFilas=sentencia.executeUpdate(strSQL); System.out.println("DAO:Hace una insert"); } catch (Exception e) { e.printStackTrace(); } sentencia.close(); con.close(); return numFilas; }

Model
Contenid o:
- Introduccin - Action Bean - System State Beans - BusinessLogic Beans - Accediendo a BD

Introduccin
El Model comprende todos los Objetos de Negocio donde se implementa la lgica de negocio (el "how it's done") y donde se debe soportar todos los requisitos funcionales del Sistema sin mezclarlo con partes correspondientes al workflow (el "what to do") que corresponden al Controller.

Action Bean
Generalmente, los Action Beans siempre realizan las siguientes acciones: 1. Obtener los valores necesarios del Action Form, JavaBean, request, session o de donde sea. 2. Llamar a los objetos de negocio del Model. 3. Analizar los resultados, y segn los mismos retornar el ActionForward correspondiente. Veamos entonces un ejemplo de Action Bean: package com.jao.controladores.consultas.actions; import import import import import import import import com.jao.controladores.consultas.forms.consultaUsuariosForm; com.jao.dao.usuarioDao; java.util.ArrayList; javax.servlet.http.HttpServletRequest; javax.servlet.http.HttpServletResponse; org.apache.struts.action.ActionForm; org.apache.struts.action.ActionForward; org.apache.struts.action.ActionMapping;

/** * * @author JAO */ public class altaUsuariosAction extends org.apache.struts.action.Action { private static final String SUCCESS = "success";

private static final String ERROR = "error"; private consultaUsuariosForm formulario; public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { String paginaRetorno=""; int numFilas=0; try { formulario =(consultaUsuariosForm) form; usuarioDao usuDAO=new usuarioDao(); numFilas=usuDAO.insert(formulario); if(0<numFilas){ ArrayList alUsuarioAlta= new ArrayList(); alUsuarioAlta.add(formulario); request.setAttribute("MiLista", alUsuarioAlta); paginaRetorno=SUCCESS; }else{ request.setAttribute("mensaje", "no se ha podido realizar la insercion"); paginaRetorno=ERROR; } } catch (Exception e) { e.printStackTrace(); request.setAttribute("mensaje", "no se ha podido realizar la insercion"); paginaRetorno=ERROR; } return mapping.findForward(paginaRetorno); } }

System State Beans


Los System State Beans son el conjunto de objetos de negocio que representan el estado actual del sistema, por ejemplo: el carrito de la compra que el usuario va modificando a lo largo de su interaccin con la aplicacin. Estos objetos de negocio sern tpicamente JavaBeans o EJBs de los que se guardar referencia en la sesin del usuario, que sern modificados desde los Action y que sern consultados desde las JSPs. Esta clase de objetos no debiera tener ningn conocimiento de la View.

BusinessLogic Beans
Los objetos de negocio son los que implementan la lgica de negocio, el cmo hacer las cosas y su propia persistencia. Estos objetos de negocio no debiera tener ningn conocimiento de la View o el Controller de forma que debieran ser perfectamente reutilizables para implementar soporte a distintas interfaces y hasta para incluirse en nuevas aplicaciones.

Accediendo a BD
Con Struts se puede definir un datasource para una aplicacin desde el struts-config.xml (ms informacin en la seccin "The Action Mappings Configuration File" del "Struts User Manual"). Este datasource nos permite obtener una connection desde un Action y desde all utilizarlo o

pasarlo al Model. Muy prctico. Este es un ejemplo de acceso a una conexin desde un Action: public ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { javax.sql.DataSource dataSource; java.sql.Connection myConnection; ... try { dataSource = servlet.findDataSource(null); myConnection = dataSource.getConnection(); ... } catch (SQLException sqle) { getServlet().log("Connection.process", sqle); } finally { ... try { myConnection.close(); } catch (SQLException e) { getServlet().log("Connection.close", e); } } }

View
Contenid o:
- Introduccin -

Internacionalizacin

- Veamos la receta

Introduccin
La View comprende las JSP (principalmente) y los servlets involucrados en la generacin de la interfaz de usuario o con otros Sistemas. Struts provee soporte para construir aplicaciones multi-idioma, interaccin con formularios y otras utilidades mediante la utilizacin de Tags especiales (TagLibraries).

Internacionalizacin
Lo podemos abreviar en la siguiente receta: 1. Crear un archivo de texto (ej: MiAplicacion.properties) en el directorio donde se encuentren las clases de la aplicacin (ej: d:\com\empresa\aplicacion) donde se contengan las claves y valores con el formato clave.subclave=texto de los textos que pertenezcan al idioma principal. Ejemplo: ... application.title= Demo de Struts en APLICACION index.header=Bienvenido a la Demo de Struts en APLICACION ... 2. Para cada idioma alternativo se crear un archivo nuevo que se llame igual pero que termine en "_xx.properties" siendo xx el cdigo ISO de idioma (ej: MiAplicacin_en.properties). 3. En struts-config.xml se debe configurar el Tag /servlet/init-param/param-name application y ponerle como param-value la localizacin del archivo con el idioma principal. Ejemplo: <servlet> <servlet-name>action</servlet-name> ... <init-param> <param-name>application</param-name> <param-value>com.empresa.aplicacion.MiAplicacion</param-value> </init-param> ... 4. En web.xml deberemos inclur: <web-app>

... <taglib> <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri> <taglib-location>/WEB-INF/struts-bean.tld</taglib-location> </taglib> ... </web-app> 5. En las JSPs donde utilicemos la internacionalizacin deberemos incluir al comienzo: ... <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> ... para declarar que utilizaremos la TagLibrary struts-bean con el prefijo bean y definida en /WEBINF/struts-bean.tld 6. Y finalmente, utilizaremos el Tag <bean:message key="clave.subclave"/> donde clave y subclave corresponden al texto por el que se reemplazar segn el idioma del usuario. Ejemplo ... <TITLE><bean:message key="application.title"/></TITLE> ... Por defecto Struts asigna a cada usuario el idioma principal de la aplicacin. Si se utiliza el tag <html:html locale="true"> (reemplaza a "<html>" y debe cerrarse con "</html:html>") entonces se utilizar el primero de los idiomas soportados por la aplicacin que se encuentre en el header "Accept-Language" enviado por su navegador. Pero si se desea proponerle al usuario una lista de idiomas entonces ste podr cambiarse mediante session.setAttribute( Action.LOCALE_KEY, new java.util.Locale(country, language)) donde country y language sern el string del pas e idioma a establecer. Adems de texto podran incluirse variables (al igual que se hace en los println) y hasta formato de datos. Para ms informacin ver la documentacin oficial de Sun disponible en http://java.sun.com/j2se/1.3/docs/guide/intl/ . Forms Una de las tareas que durante el desarrollo de una aplicacin insume mucho trabajo (aunque en realidad no lo merezcan) es la interaccin con formularios, ya sea para editar u obtener nueva informacin. Las comprobaciones, la gestin de errores, el volver a presentarle el mismo form al usuario con los valores que puso y los mensajes de error y un largo etctera estn soportadas por Struts a fines de hacernos la vida un poco ms fcil. La idea es la siguiente: todo el trabajo de comprobaciones y generacin de mensajes de error se implementa en los ActionForm y todo el trabajo de generacin de interfaz en la/s JSP.

Veamos la receta:
1. Crear el ActionForm (ver la seccin Model / ActionForm Beans) 2. Crear la pgina JSP del formulario utilizando los Tags que provee Struts (ver la seccin View / Tags). Ejemplo: ... <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

... <html:html> ... <html:form action="/logon" focus="username"> ... <h1><bean:message key="logon.header"/></h1> <html:form action="/logon" focus="username"> <h5><html:errors/></h5> <h3><bean:message key="logon.mainText"/></h3> <p><bean:message key="logon.username"/> <html:text property="username" size="16" maxlength="16"/></p> <p><bean:message key="logon.password"/> <html:password property="password" size="16" maxlength="16" redisplay=false/></p> <p><html:submit property="submit" value="Submit"/></p> <p><html:reset/></p> ... </html:form> ... </html:html> 3. Declarar el ActionForm en struts-config.xml agregando en /struts-config/form-beans el tag <form-bean name="nombreForm" type="paquete.clase"/> y en la declaracin del Action (ver la seccin Controller / Action Beans) agregar los atributos name="nombreForm", scope="(request session)", e input="paginaForm.jsp". Ejemplo: <struts-config> ... <form-beans> ... <form-bean name="logonForm" type="com.empresa.aplicacion.LogonForm"/> ... </form-beans> ... <action-mappings> ... <action path="/logon" type="com.empresa.aplicacion.LogonAction" name="logonForm" scope="request" input="/logon.jsp"> ... </action> ... <action-mappings> ... </struts-config>

Tags
Bsicamente, un Tag de JSP consiste en un Tag con formato <prefijoTagLib:nombreTag atributo=valor ... > que cuando la JSP se compila es sustitudo por una llamada a la clase TagHandler que se encarga de resolver su funcionalidad. El TagHandler extiende BodyTagSupport o TagSupport (segn si es un tag que tiene body), que implementa su funcionalidad en los mtodos doStartTag(), doEndTag(),doInitBody(), doAfterBody() (los dos ltimos slo en las que extienden BodyTagSupport), adems de los getters y setters correspondientes a sus atributos. Esta clase se define en un Tag Library Definition (archivo xml con extensin TLD donde se define el nombre del tag, la clase TagHandler que lo atiende, la definicin de sus atributos, si tiene body, etc.) que a su vez se debe declarar en el web.xml (dentro de <web-app> se pone <taglib> <taglib-uri> nombreTagLib</taglib-uri> <tagliblocation>/directorios/nombreArchivo.tld </taglib-location> </taglib>) y en la JSP donde se utilizar (<%@ taglib uri="nobreTagLib" prefix="prefijoTagLib" %>). Finalmente, el Tag que se usa en la JSP consiste en <prefijoTagLib:nombreTag atributo=valor ... >. Para ms info, ver la pgina oficial de Sun sobre TagLibraries en http://java.sun.com/products/jsp/taglibraries.html.

Controller

Introduccin
El Controller comprende la funcionalidad involucrada desde que un usuario genera un estmulo (click en un link, envo de un formulario, etc.) hasta que se genera la interfaz de respuesta. Entre medio, llamar a los objetos de negocio del Model para que resuelvan funcionalidad propia de la lgica de negocio y segn el resultado de la misma ejecutar la JSP que deba generar la interfaz resultante. Struts incluye un servlet que a partir de la configuracin de struts-config.xml recibe las solicitudes del usuario, llama al Action Bean que corresponda y, segn lo que ste retorne, ejecuta una JSP. Por consiguiente, las tareas que se deben realizar son: 1. Escribir una clase Action que extienda de org.apache.action.Action. Ver seccin "Controller Action Bean". 2. Configurar el struts-config.xml para que incluya el nuevo action mapping y sus posibles forwards de salida. Por ejemplo: <struts-config> ... <action-mappings> ... <action path="/logoff" type="com.empresa.aplicacion.LogoffAction"> <forward name="success" path="/index.jsp"/> </action> ... </action-mappings> ... </struts-config> En este caso, cuando la solicitud sea "/logoff" el Controller llamar a LogoffAction y si esta retorna un ActionForward con valor success entonces ejecutar /index.jsp. Pero... qu pasa si es una accin asociada a un formulario? La respuesta es un poco ms compleja: se debe definir un Form Bean, un Action Mapping con el Form Bean asociado y el o los forwards necesarios. Por ejemplo: <struts-config> ... <form-beans> ... <form-bean name="logonForm" type="com.empresa.aplicacion.LogonForm"/> ... </form-beans> ... <global-forwards> ... <forward name="success" path="/mainMenu.do"/> ... </global-forwards> ... <action-mappings> ... <action path="/logon" type="com.empresa.aplicacion.LogonAction" name="logonForm" scope="request" input="/logon.jsp"> </action> ... </action-mappings> ...

Carga de documentos en el servidor


Contenid o:
- Introduccin - Libreras - JSP con Formulario multipart - Cargar el documento

Introduccin:
En este apartado, veremos como cargar un documento desde una jsp para almacenarlo en el servidor, en nuestro caso, un servidor Tomcat 5.5. Para ello no necesitaremos mas que una crear una JSP, con un formulario, y un Action.java que implementar la carga del documento seleccionado desde el formulario de la JSP.

Libreras:
Para realizar esta tarea, se necesitan basicamente 2 libreras: - commons-fileupload-1.2.1jar. - commons-io-1.4.jar. Aunque si que es cierto que hay distintas versiones de estas libreras yo he utilizado para mi desarrollo estas dos. Podemos descargarlas de struts.apache.org de entre todas las versiones que dispone.

Formulario multipart:
Pues bien, ahora nos dispondremos a implementar una simple JSP con un formulario multipart que contendr un control INPUT del tipo FILE, que se engargar de almacenar el documento seleccionado: <html> <head> <meta http-equiv="Content-Type" content="multipart/form-data;"> <title>Cargar documento</title> </head> <body> <form action="/JAO/SubirFicherosServidorAction.do" method="post" enctype="multipart/form-data" > Selecciona el documento de tipo pdf y pulsa Enviar para guardarlo en servidor <input type="file" name="theFile" id="theFile"/> <html:submit title="Enviar" value="Enviar"/>

</form> </body> </html>

Cargar documento
Para cargar el documento nos tendremos que generar un action, en nuestro caso SubirFicherosServidorAction.java y aadir en el controlador struts-config.xml estas lineas: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_3.dtd">

<struts-config> <form-beans> </form-beans> <global-exceptions> </global-exceptions> <global-forwards> <forward name="welcome" path="/Welcome.do"/> </global-forwards> <action-mappings> <action path="/SubirFicherosServidorAction" type="com.jao.controladores.consultas.actions.SubirFicherosServidorAction" scope="request" validate="false" > <forward name="success" path="/JSPs/cargarDocumExito.jsp" /> <forward name="error" path="/JSPs/cargarDocumError.jsp" /> </action> ..... y en el action SubirFicherosServidorAction.java deberemos aadir lo siguiente: package com.jao.controladores.consultas.actions; import import import import import java.io.File; java.util.List; java.util.Iterator; javax.servlet.http.HttpServletRequest; javax.servlet.http.HttpServletResponse;

import import import import /*

org.apache.struts.action.ActionForm; org.apache.struts.action.ActionForward; org.apache.struts.action.ActionMapping; org.apache.commons.fileupload.*;

* @author JAO */ public class SubirFicherosServidorAction extends org.apache.struts.action.Action { private static final String SUCCESS = "success"; private static final String ERROR = "error";

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { String paginaRetorno="";

try{ String tempStore = System.getProperty("java.io.tmpdir"); int maxMemorySize = -1; FileUpload sfu = new FileUpload(new org.apache.commons.fileupload.disk.DiskFileItemFactory(maxMemorySize, new File(tempStore))); sfu.setSizeMax(maxMemorySize); List <FileItem>fileItems = sfu.parseRequest(request); Iterator itr = fileItems.iterator(); while(itr.hasNext()) { FileItem fi = (FileItem)itr.next(); if (!fi.isFormField()) { File file = new File(fi.getName()); fi.write(file); paginaRetorno=SUCCESS; } } paginaRetorno=ERROR; }catch(Exception e){ e.printStackTrace(); paginaRetorno=ERROR; } return mapping.findForward(paginaRetorno);

} }

Vous aimerez peut-être aussi