Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Manual Básico de Struts
Manual Básico de Struts
• Introducción
o ¿Qué es Struts?
o ¿Cómo funciona esto en aplicaciones Web?
o ¿Para qué sirve?
o ¿Licencia?
o ¿Y para qué este manual básico?
o ¿Dónde encuentro más info?
• Model
o Intro
o Action Bean
o System State Beans
o BusinessLogic Beans
o Accediendo a BD
• View
o Intro
o Internacionalización
o Forms
o Tags
• Controller
o Intro
o ActionForm Beans
• ¿Cómo pongo en funcionamiento Struts?
Introducción
¿Qué es Struts?
Un framework es la extensión de un lenguaje mediante una o más jerarquías de clases que implementan
una funcionalidad y que (opcionalmente) pueden ser extendidas. El framework puede involucrar
TagLibraries.
El navegador genera una solicitud que es atendida por el Controller (un Servlet especializado). El mismo se
encarga de analizar la solicitud, seguir la configuración que se le ha programado en su XML y llamar al
Action correspondiente pasándole los parámetros enviados. El Action instanciará y/o utilizará los objetos de
negocio para concretar la tarea. Según el resultado que retorne el Action, el Controller derivará la
generación de interfaz a una o más JSPs, las cuales podrán consultar los objetos del Model a fines de
realizar su tarea.
El controlador ya se encuentra implementado por Struts, aunque si fuera necesario se puede heredar y
ampliar o modificar, y el workflow de la aplicación se puede programar desde un archivo XML Las acciones
que se ejecutarán sobre el modelo de objetos de negocio se implementan basándose en clases
predefinidas por el framework y siguiendo el patrón Facade. Y la generación de interfaz se soporta
mediante un conjunto de Tags predefinidos por Struts cuyo objetivo es evitar el uso de Scriplets (los trozos
de código Java entre "<%" y "%>"), lo cual genera ventajas de mantenibilidad y de perfomance (pooling de
Tags, caching, etc).
Logísticamente, separa claramente el desarrollo de interfaz del workflow y lógica de negocio permitiendo
desarrollar ambas en paralelo o con personal especializado.
También es evidente que potencia la reutilización, soporte de múltiples interfaces de usuario (Html, sHtml,
Wml, Desktop applications, etc.) y de múltiples idiomas, localismos, etc.
¿Licencia?
Struts está disponible bajo la licencia "free-to-use-license" de la Apache Software Foundation (ver
http://www.apache.org/LICENSE-1.1)
Para simplificar el "first touch" y para explicar Struts desde el punto de vista del desarrollo de aplicaciones
Web.
No pretende ser un tutorial, una guía del usuario ni un manual de referencia. Ellos ya se han escrito y están
disponibles en las direcciones que se mencionan en la sección "¿Dónde encuentro más info?"
• http://jakarta.apache.org/struts
• http://jakarta.apache.org/struts/userGuide
• http://jakarta.apache.org/struts/api/index.html
• http://jguru.com/faq/Struts
• http://jguru.com/forums/Struts
• http://jakarta.apache.org/struts/#Involved
Model
Intro
El Model comprende todos los Objetos de Negocio donde se implementa la lógica 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
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 según los mismos retornar el ActionForward correspondiente.
// Obteniendo atributos
if (mapping.getAttribute() != null) {
if ("request".equals(mapping.getScope()))
request.removeAttribute(mapping.getAttribute());
else
session.removeAttribute(mapping.getAttribute());
}
// Pasando el control a la siguiente página
return (mapping.findForward("success"));
}
}
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 interacción con
la aplicación. Estos objetos de negocio serán típicamente JavaBeans o EJBs de los que se guardará
referencia en la sesión del usuario, que serán modificados desde los Action y que serán consultados desde
las JSPs.
BusinessLogic Beans
Los objetos de negocio son los que implementan la lógica de negocio, el cómo hacer las cosas y su propia
persistencia. Estos objetos de negocio no debiera tener ningún 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 aplicación desde el struts-config.xml (más
información en la sección "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 práctico.
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
Intro
La View comprende las JSP (principalmente) y los servlets involucrados en la generación de la interfaz de
usuario o con otros Sistemas. Struts provee soporte para construir aplicaciones multi-idioma, interacción
con formularios y otras utilidades mediante la utilización de Tags especiales (TagLibraries).
Internacionalización
para declarar que utilizaremos la TagLibrary struts-bean con el prefijo bean y definida en /WEB-
INF/struts-bean.tld
Por defecto Struts asigna a cada usuario el idioma principal de la aplicación. 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 aplicación 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 serán el string del país e idioma a
establecer.
Además de texto podran incluirse variables (al igual que se hace en los println) y hasta formato de datos.
Para más información ver la documentación 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 aplicación insume mucho trabajo (aunque en realidad no
lo merezcan) es la interacción con formularios, ya sea para editar u obtener nueva información. Las
comprobaciones, la gestión de errores, el volver a presentarle el mismo form al usuario con los valores que
puso y los mensajes de error y un largo etcétera están soportadas por Struts a fines de hacernos la vida un
poco más fácil.
Veamos la receta:
El TagHandler extiende BodyTagSupport o TagSupport (según si es un tag que tiene body), que
implementa su funcionalidad en los métodos doStartTag(), doEndTag(),doInitBody(),
doAfterBody() (los dos últimos sólo en las que extienden BodyTagSupport), además de los getters y
setters correspondientes a sus atributos. Esta clase se define en un Tag Library Definition (archivo xml con
extensión TLD donde se define el nombre del tag, la clase TagHandler que lo atiende, la definición 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> <taglib-
location>/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 más info, ver
la página oficial de Sun sobre TagLibraries en http://java.sun.com/products/jsp/taglibraries.html.
• html: http://jakarta.apache.org/struts/struts-html.html
• bean: http://jakarta.apache.org/struts/struts-bean.html
• logic: http://jakarta.apache.org/struts/struts-logic.html
• nested: http://jakarta.apache.org/struts/struts-nested.html
Las clases TagHandlers que implementan dicha funcionalidad están documentadas en:
• html: http://jakarta.apache.org/struts/api/org/apache/struts/taglib/html/package-summary.html
• bean: http://jakarta.apache.org/struts/api/org/apache/struts/taglib/bean/package-summary.html
• logic: http://jakarta.apache.org/struts/api/org/apache/struts/taglib/logic/package-summary.html
• nested: http://jakarta.apache.org/struts/api/org/apache/struts/taglib/nested/package-summary.html
Controller
Intro
El Controller comprende la funcionalidad involucrada desde que un usuario genera un estímulo (click en un
link, envío 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 lógica de negocio y según el
resultado de la misma ejecutará la JSP que deba generar la interfaz resultante.
Struts incluye un servlet que a partir de la configuración de struts-config.xml recibe las solicitudes del
usuario, llama al Action Bean que corresponda y, según 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 sección "Controller
Action Bean".
2. Configurar el struts-config.xml para que incluya el nuevo action mapping y sus posibles forwards
de salida. Por ejemplo:
3. <struts-config>
4. ...
5. <action-mappings>
6. ...
7. <action path="/logoff" type="com.empresa.aplicacion.LogoffAction">
8. <forward name="success" path="/index.jsp"/>
9. </action>
10. ...
11. </action-mappings>
12. ...
13. </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 acción asociada a un formulario? La respuesta es un poco más 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>
...
</struts-config>
En este caso se ha definido un global-forward que, como su nombre lo indica, viene a ser un
forward que se aplica a todos los action-mappings (excepto que se re-defina para alguno en
particular).
14. Incluir los links (preferentemente utilizando <html:link>) o forms (necesariamente utilizando
<html:form>) necesarios en las JSPs correspondientes.
ActionForm Beans
Los ActionForm Beans son clases que extienden ActionForm y que implementan métodos get y set para
cada una de los inputs de un form de una página, y los métodos validate y reset.
Cuando un usuario completa un formulario y lo envía, el Controller busca en el scope especificado el
ActionForm Bean correspondiente (todo esto configurado en el struts-config.xml) y si no lo encuentra lo
crea. Luego realiza un set por cada input del form y finalmente llama al método validate. Si éste retornara
uno o más errores, el Controller llamaría a la JSP del formulario para que ésta lo volviera a generar (con los
valores establecidos por el usuario) e incluyera el o los mensajes de error correspondientes. Si todo
estuviese bien, llamaría al método perform del Action (también configurado en el struts-config.xml)
pasándole el ActionForm Bean como parámetro para que sea utilizado para obtener los valores de los
datos.
Si bien el ActionForm tienen características que corresponden al Model, los ActionForm pertenecen a la
View. Justamente uno de estos puntos comunes es la validación de datos y a fines de evitar la duplicación
de funcionalidad, si un desde un ActionForm debe realizar controles de validación que se hubiesen
implementado en un objeto de negocio entonces se debería utilizar una instancia de éste para efectuarlos.
Ejemplo:
Como todo framework, Struts consiste en una librería de clases y una serie de configuraciones por lo que
su instalación es muy similar en todos los servidores de aplicaciones que provean (o puedan agregársele)
soporte de:
38. Modificar el WEB-INF/web.xml de la aplicación para incluir la definición de los TagLibraries. Por
ejemplo:
39. <web-app>
40. ...
41. <taglib>
42. <taglib-uri>strutsBean</taglib-uri>
43. <taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
44. </taglib>
45.
46. <taglib>
47. <taglib-uri>strutsHtml</taglib-uri>
48. <taglib-location>/WEB-INF/struts-html.tld</taglib-location>
49. </taglib>
50.
51. <taglib>
52. <taglib-uri>strutsLogic </taglib-uri>
53. <taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
54. </taglib>
55.
56. <display-name></display-name>
57.
58. <description></description>
59. ...
60. </web-app>
61. Agregar la definición de las TagLibraries en las JSPs que se utilicen. Ejemplo:
62. <%@ taglib uri="strutsBean" prefix="bean" %>
63. <%@ taglib uri="strutsHtml" prefix="html" %>
64. <%@ taglib uri="strutsLogic" prefix="logic" %>
65. Crear un struts-config.xml donde se configure el Controller según se describió en las secciones
anteriores.
Si bien están comenzando a surgir aplicaciones que gestionan la configuración de Struts en forma visual
(Camino, StrutsConsole, etc.) es muy recomendable familiarizarse primero con la configuración manual
antes de utilizar estas herramientas