Struts 2

Struts 2 es, como el nombre sugiere, la nueva versión del popular framework de desarrollo web en Java Apache Struts. Sin embargo, contrariamente a lo que cabría esperar, el código de ambos tiene poco que ver, dado que Struts 2 no se basa en el código de Struts 1.x, sino en el de otro framework de desarrollo web en Java llamado WebWork, un framework que el creador de Struts consideraba superior a Struts 1.x en varios aspectos.

Struts 2 está basado en el patrón MVC (Modelo-Vista-Controlador), una arquitectura que busca reducir el acoplamiento dividiendo las responsabilidades en 3 capas claramente diferenciadas:

  • El modelo, que hace referencia a los datos que maneja la aplicación y las reglas de negocio que operan sobre ellos y que se traducen en Struts 2 en las acciones.
  • La vista, encargada de generar la interfaz con la que la aplicación interacciona con el usuario. En Struts 2 equivale a los resultados.
  • El controlador, que comunica la vista y el modelo respondiendo a eventos generados por el usuario en la vista, invocando cambios en el modelo, y devolviendo a la vista la información del modelo necesaria para que pueda generar la respuesta adecuada para el usuario. El controlador se implementa en Struts 2 mediante el filtro FilterDispatcher

Por supuesto, podríamos utilizar JSP y servlets para crear una aplicación utilizando el patrón MVC: en una aplicación con JSP y servlets clásica se suelen utilizar páginas JSP para la vista, un servlet como controlador (patrón front controller) y POJOs (Plain Old Java Objects) para el modelo. El modelo, a su vez, suele estar dividido en dos subcapas siguiendo el patrón DAO (Data Access Object).

Sin embargo no tiene sentido reinventar la rueda cuando podemos recurrir a un framework, como Struts 2, para que se encargue de obtener y transformar los parámetros de las peticiones del cliente, validar los datos, buscar qué acción se debe realizar en el modelo según la petición, buscar la página a mostrar al usuario según la respuesta del modelo, proporcionar los datos del modelo a la vista, ocuparse de la internacionalización, etc.

Veamos cómo crear un pequeño “Hola mundo” con Struts 2. O mejor aún: un hola algo.

Como IDE utlizaremos Eclipse. También necesitaremos un servidor de aplicaciones o un contenedor web, como Tomcat. Para ver cómo integrar tu servidor en Eclipse puedes consultar la entrada Eclipse y Tomcat, adaptando los pasos necesarios en caso de utilizar un servidor distinto.

Por supuesto también necesitaremos descargar Struts 2 desde su página web. En principio basta con descargar las librerías que componen Struts 2 y sus dependencias (Essential Dependencies Only) aunque también os puede interesar descargar la versión completa (Full Distribution) que incluye además la documentación, el código fuente, y distintas aplicaciones de ejemplo.

En todo caso una vez hemos descargado Struts 2, Eclipse y Tomcat ya está todo listo para comenzar a trabajar.

Abrimos Eclipse y nos dirigimos a File -> New -> Dynamic Web Project para crear un nuevo proyecto para web dinámica. En Project name introducimos el nombre que queramos utilizar para el proyecto, por ejemplo, hola. Pulsamos Finish.

Copiamos las librerías básicas a la carpeta WebContent\WEB-INF\lib. Estas son commons-fileupload, commons-logging, freemarker, ognl, struts2-core y xwork. Hacemos clic con el botón derecho sobre el proyecto, y seleccionamos Refresh para que Eclipse las vea.

Editamos el descriptor de despliegue (web.xml) para añadir el filtro que sirve a Struts 2 a modo de punto de entrada a la aplicación: FilterDispatcher. Hacemos doble clic sobre “Deployment Descriptor: hola” y sustituimos el contenido por el siguiente:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>hola</display-name>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <filter>
        <filter-name>struts</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

Como vemos lo único que estamos haciendo es indicar al contenedor web (Tomcat en este caso) que toda petición, tenga esta la URL que tenga, debe pasar por el filtro FilterDispatcher. FilterDispatcher es en realidad el controlador de nuestra aplicación; nosotros sólo tendremos que ocuparnos de la vista y el modelo, llamados resultados y acciones en la terminología de Struts 2.

Ahora vamos a crear la página de inicio de nuestra aplicación. Como en el descriptor de despliegue hemos indicado que index.jsp es uno de los “archivos de bienvenida” (welcome-file), cuando en la URL no se especifique el archivo a mostrar dentro del directorio se mostrará por defecto index.jsp; de esta forma tanto http://localhost:8080/hola/index.jsp como http://localhost:8080/hola/ mostrarán nuestra nueva página.

Hacemos clic con el botón derecho sobre WebContent y seleccionamos New -> JSP, en File name escribimos index.jsp y pulsamos Finish. El contenido de la página será el siguiente:

<%@ taglib uri="/struts-tags" prefix="s" %>

<html>
<body>
<s:form action="Hola">
<s:textfield name="nombre" label="Nombre"/>
<s:submit/>
</s:form>
</body>
</html>

Como vemos se utiliza la directiva taglib de JSP para indicar al contenedor que queremos usar la librería de etiquetas struts-tags, para las que se usará el prefijo “s”. Los nombres de las etiquetas de struts-tags que utilizamos son bastante descriptivos: estamos creando un formulario (<s:form></s:form>) con un campo de texto (<s:textfield/>) y un botón de enviar (<s:submit/>), que mandará los datos a la acción Hola (campo action del formulario).

Veamos ahora el código de la acción Hola. Las acciones en Struts 2 son clases Java que suelen implementar la interfaz Action o extender la clase ActionSupport (suelen, porque no es obligatorio). Creamosla haciendo clic con el botón derecho sobre Java Resources:src y seleccionando New -> Class; en Name, introducimos Hola y pulsamos Finish. Al crear el WAR de la aplicación el archivo .class acabará en WebContent/WEB-INF/classes. El código de la acción es el siguiente:

import com.opensymphony.xwork2.ActionSupport;

@SuppressWarnings("serial")
public class Hola extends ActionSupport {
    private String nombre;

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String execute() {
        System.out.println(nombre);
        return SUCCESS;
    }
}

El código a ejecutar por nuestra acción está contenido en un método execute(). Como vemos la funcionalidad es bastante pobre, una simple excusa para utilizar una acción, ya que podríamos haber prescindido totalmente de ella. Sin embargo este código tan sencillo, que imprime en la consola el nombre que el usuario introdujo en el formulario, pone de manifiesto algo bastante interesante y es que no aparece por ningún lado un objeto HttpServletRequest ni similar del que obtener el valor del parámetro nombre del formulario, luego, ¿de dónde sale la propiedad nombre?

Lo cierto es que Struts 2 (o más bien el interceptor param de Struts 2) nos tiene preparada una sorpresa, y es que basta con crear getters y setters con los nombres de los campos de los formularios para que estos se rellenen auto mágicamente, incluso aunque las propiedades no sean cadenas y sea necesaria una sencilla conversión. Este es el trabajo del interceptor param, como hemos dicho.

Los interceptores son unos de los elementos más importantes de Struts 2. Se trata de objetos que ejecutan código antes y después de una cierta acción, de forma que podamos añadir nueva funcionalidad no relacionada directamente con el modelo de forma modular. Tenemos interceptores para logging, para validación, para capturar excepciones, etc.

Como vemos el método execute devuelve un string indicando el resultado de la acción. En este caso se devuelve SUCCESS, que es una constante proveniente de la clase que extendemos, ActionSupport, y cuyo valor es “success”. ¿Y de qué sirve esto? Pues para que Struts 2 sepa a qué página redirigir, según el mapping que definimos en el archivo de configuración de Struts 2 struts.xml.

Vamos a crear este archivo. Hacemos clic con el botón derecho sobre Java Resources:src, seleccionamos New -> XML, pulsamos Next y seleccionamos como nombre struts.xml y como directorio de destino src. Este archivo acabará en WebContent/WEB-INF/classes al crear el WAR de la aplicación. Su contenido debe ser el siguiente:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
    <package name="mi-paquete" extends="struts-default">
        <action name="Hola" class="Hola">
            <result name="success">/hola.jsp</result>
        </action>
    </package>
</struts>

En este caso lo que estamos haciendo es indicar al framework que queremos que se ejecute el código de la clase Hola cuando llegue una petición a Hola.action, y que se muestre la página hola.jsp como resultado cuando el valor devuelto sea “success”.

Vamos a ver por último el código de hola.jsp. Hacemos clic con el botón derecho sobre WebContent y seleccionamos New -> JSP; en File name escribimos hola.jsp y pulsamos Finish. El contenido del archivo es el siguiente:

<%@ taglib uri="/struts-tags" prefix="s" %>

<html>
<body>
Hola <s:property value="nombre"/>
</body>
</html>

En esta página lo único que hacemos es utilizar la etiqueta <s:property/> para mostrar la propiedad nombre de la acción, que se toma de una pila de valores llamada ValueStack.

Solo resta probar el código de nuestra aplicación. Arrastramos el proyecto sobre nuestra instancia de Tomcat en la pestaña Servers, e iniciamos el servidor haciendo clic con el botón derecho sobre él y seleccionando Start. Si abrimos la URL http://localhost:8080/hola/ en nuestro navegador y todo funciona correctamente, deberíamos ver algo como esto:

Struts 2 ejemplo




95 pensamientos en “Struts 2”

  1. A mi me costó un tiempo empezar a utilizar Struts1, luego quise ponerme con Struts2 pero como tú bien dices.. no se parecen en nada!! me dio pereza .-p, me quedé en la rama 1 🙂

    1. Lo que no entiendo de Blaxter es su logica. Hay que ser Statico Abstracto y Final para leerse un manual de PM sobre Struts2 y luego soltar en plan nenaza ñoña “Java en Web no gracias”. Por no entrar en el tema que, con semejante afirmacion te intuyo un experto que te haces necesidades en GWBasic con largos años de experiencia en el MKDIR, a pesar de que nunca dominaste demasiado bien el CD ni el RD. En definitiva, a alguien tan Extend como para realizar semejante comentario solamente le puedo asignar por cerebro una Interface vacia y sin fundamento, gracias a Dios no le aplicaria la clausula Final, es tu dia de suerte AbstractBoy.

    2. son puros giles pa contestar, esas gueas de ruby and rails php y todo lo que no es java son buenos pero preguntense por que las empresas grandes no los usan y usan java por soporte nada mas qeu por eso toda la otra huea es una mierda sirve para cosas pero finalmente tenis que subencionarlos con maquinas escalamientos horizontales verticales paos lesos, se nota que hacen aplicaciones culias rascas q soportan un par de registros, pero no sistemas distribuidos, en donde prima lo convencional, y spring sea roo puro la huea que sea, no tiene soporte mas que ungrupo de hueones que programa y si los llamas con raja los encontrai si en las comunidades pero no dedicados al 100% en cambio JEE J2ee en base a ORACLE O WEbSpehere IBM deberia ser lo estandar no lo mejor pero lo estandar GILES todo eso que hablan de configuraciones inyecciones y no se cuanta guea es pura mierda por que lo demas lo hace la herramienta ahora lo importante es la arquitectura y casos que pueden hacer mierda la session y ser fino y elegante con patrones de diseño que ademas ya viene incluido en Struts parte WEB MVC Y PABAJOO PAL NEGOCIO EJB Spring la huea que querai pero con patrones PARA LOS CAMINOS COMUNES Y NESECIDADES DIFERENTES GILES NERD!!

  2. @Blaxter.. yo monté todo el software jurídico de mi empresa con Java como tecnología para la web.. y vamos.. super mantenible.. 🙂
    A día de hoy.. si tuviera que empezar otro mega-proyecto volvería a usar JSP. Para webs normalitas… siempre PHP..

      1. Jaja madre mia como sois los fanboys. Yo pensaba que esto solo pasaba con las videoconsolas y demás donde hay mucho niño suelto. Sin menospreciar en absoluto el desarrollo web en Java a quien diga que PHP no es potente le diría que un lenguaje de programación es tan potente como lo sea el cerebro del que lo utiliza. Es cierto que crear un framework PHP5 bien hecho no es trivial pero hay empresas, como por ejemplo Softonic que son lideres en su sector y cuentan en decenas de millones las visitas que obtienen mensualmente. Ah y eso Utilizando MySQL en vez de Oracle que ya es decir. Además es un milagro lo bien que va PHP teniendo en cuenta lo flexible que es (Java está super tipado y, aunque eso en realidad es bueno porque obliga a hacer las cosas bien…a veces desespera un poco a los que no somos muy buenos programadores).

  3. Todo lo que comentas lo puedes hacer también con spring mvc, lo que yo no entiendo es porque existen proyectos que utilizan spring + struct2…!

    ¿Que ventajas puede tener utilizar spring + struct2 en lugar de utilizar todas las ventajas de spring (IoC, AOP) con spring mvc?

    1. es más sencillo configurar el VC de struts2 que el VC de spring, el mvc tiene acceso “Directo” a los objetos HttpServletRequest el struts2 te los encapsula, cada uno tiene sus bondades y no no hay ningún limitante para usar todo lo que dices de Spring la “suite” completa, pero es según requerimientos y comodidad

  4. @blu yo Struts lo suelo utilizar con Spring IoC para la inyección de dependencias. Cada uno tiene sus ventajas y sus desventajas, pero es lo único que le echo en falta a Struts respecto de Spring.

  5. @Zootropo pero a la conclusión a la que quiero llegar (debido a que nunca he utilizado struts y lo desconozco) es porque uno decide utilizar strut2 junto con spring, en lugar de emplear un solo framework (ya que spring aporta de un modo equivalente la funcionalidad que comentas en este post).

    Dicho de otro modo, hay algo que aporte la inclusión de struts2 cuando ya se está utilizando spring porque spring tenga carencias que son suplidas por struts o se reduce más a una cuestión de gustos.

    1. Es muy bueno!!, pero lamentablemente no todos lo usan y por lo tanto no tienen tanto soporte, ya ves que eso preocupa regularmente “ay! y el soporte???”, y esta genialisisisimo ese ruby

  6. Pingback: El blog de Marvin & familia » Blog Archive » Lo mejor de la semana - GNU/Linux para principiantes y mucho más…

  7. Pingback: Etiquetas Struts 2

  8. @Zootropo, actualmente ruby o python.

    Java sería una de mis últimas elecciones como lenguaje (y tengo bastantes decenas de miles de líneas escritas en él) y desde luego ni siquiera una opción para apps web.

  9. No se en que se basan para decir que Java sería una de las últimas elecciones para desarrollar una aplicacion web. Dejando de lado la perfomance (que depende del application server elegido y configurado), Java está por arriba del resto en lo que se refiere a portabilidad. El diseño de objetos es un mundo complejo y hay que saber mucho de el antes de escribir una linea de codigo en Java.

    1. estoy deacuerdo con vos yo hace ya un año y medio que programo con Java y me parece que es espectacular no he conocido otro lenguaje en donde se puedan hacer todas las cosas que se hacen con java PHP seria la ultima eleccion que tomaria para realizar cualquier aplicacion sea web o no me parece mu vulnerable

  10. ¿Alguien a probado el ejemplo?. Yo lo he hecho tal y como viene y no me muestra el nombre. No se si a alguien le ocurre lo mismo. Soy novato en esto y me gustaría poder hacerlo correctamente. Gracias y un saludo a todos.

  11. Struts 2 es muy potente!! yo les diria que vale la pena que den el salto!! puedes manejar facilmente la internacionalizacion, request,session… y sus etiquetas para jsp son muy buenas!! ademas lo puedes conectar con todo (ajax ,flex,tiles).

    saludos..

    pd. php es potente.. pero es muy cohino comparado con java

  12. @Manu He seguido varios manuales parecidos a este y ESTE es el unico que me ha funcionado, ademas con el codigo completo que introducir en cada archivo de configuracion y con un seguimiento al detalle.

    Prueba a empezar completamente de nuevo… ;).

  13. Estoy leyendo el libro de Struts 2 de anaya Multimedia y el ejemplo que me dieron esta muy basico y claro, me ayudo ,mucho gracias!!!!

  14. A mi me aparece este mensaje de error

    type Informe de estado

    mensaje

    descripci�n El recurso requerido () no est� disponible.

    A que puede deberse

    1. Pablo el problema que tienes es que tu Struts-config-xml no esta tomando el camino que estas inçdicando en el action de tu form por lo tanto no entiende donde debe ir a buscar el action es por eso que te dice que no esta disponible muestrame tu codigo y con gusto te ayudo

  15. muchas gracias por el ejemplo, estoy muy interesado en realizar aplicaciones web bajo la plataforma de java y con este ejemplo sencillo y basico empiezo con el pie derecho en el mundo de la programacion. XD

  16. Gracias por el ejemplo, en eclipse no he tenido ningún problema, pero he intentado pasarlo a jdevelopper y aunque parte me funciona, ahora intento crearme un submit en una jsp y no me redirecciona al action del struts.xml, es decir, los que tenía creados antes si pero lo que me creo nuevos no los interpreta, es un poco raro no??, sabría alguién que puede estar pasando??.
    Muchas gracias, saludos

  17. MMM pues no le hagan al cuento programen en lo que se necesite php jsp con los framework que se adapten que si uno es mejor ,muchos de ustedes no han manejado mas de un entorno de desarrollo , y esa que dice que java no sirve o que seria su ultima opcion vamos chaval ahi se ve lo poco que conoces nunca subestimes a un lenguaje java es mas de que puedes saber son dos grandes mundos mejor conocelo primero y despues opina.

  18. Hola, una pregunta, estoy intentando integrar ajax y struts 2, y me da problemas que todos los actions tengan un result a una jsp, ya que se me recarga la página entera y usar ajax entonces no es interesante. Se que se puede redirigir a otro action, pero no veo que solucione mi problema. Tienes alguna idea de como montarlo?. ¿Hay alguna manera de hacer que un action no redirija a “nada”?

    Gracias, el tutorial muy completo. Saludos.

    1. Un action siempre ha de dirigirte a algo. Para que funcione Ajax con Struts2, debes tener una página superior, que llamaremos “padre”, y otra que la llamaremos “hija”.
      La página “padre” ha de tener una llamada a esa capa “hija”. Una vez estés trabajando en la capa hija, aquellas acciones que quieras que se recarguen solo la capa “hija”, en el target has de poner el nombre del div de la capa hija.
      Es un poco lioso, pero si estás interesado puedo explciartelo.

  19. Me sale este error
    :
    30-ago-2009 23:07:12 com.opensymphony.xwork2.util.logging.commons.CommonsLogger warn
    ADVERTENCIA: Could not find action or result
    There is no Action mapped for namespace / and action name . – [unknown location]
    at com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:177)

  20. Alguien que le diga al Blaxter que empresas como ORACLE e IBM usan la tecnologia de JAVA para crear grandes aplicaciones empresariales.

    Ademas, programadores de PHP muchos… de Java pocos pero son mejor pagados. Abusados !

  21. Como decia antonio creo que no es neceario decidir cual es mejor o peor tecnología pues la mayoria de nosotros somos programadores que nos mandarán a la guerra en cualquier lenguaje, yo en particular domino muchos lenguajes y tecnologias, creo que lo realmente importante son los conceptos de OO que nos sirven para cualquier lenguaje, esto mas el uso de patrones de diseño no ayudan a realizar codigos de calidad. Actualmente trabajo en c#, no me gusta .Net, de hecho vengo del mundo de Java (tb pase por php), creo que me demoré 1 dia en cambiarme de java a c#, el codigo es muy parecido, lo importante es la OO, lo mismo me paso con flex (ActionScript3) no tenia idea del lenguaje, pero la OO ayuda a salir de los problemas.
    Saludos

  22. Pingback: Lo mejor del 2009

  23. Hola solo tengo una pregunta que diferencia existe entre usar los componentes que struts ofrece para el diseño de la pagina y componentes input normales de html?

  24. Uhuru programar en python da gusto.

    Seguro que no lo has probado.

    Sin embargo:

    “¿Java para aplicaciones web? No, gracias.”

    Me parece una tolonteria… Java es un lenguaje de programacion cojonudo y esta muy evolucionado. Y lo peor es brutalmente mas eficaz que python o ruby.

    Otra cosa es que se haga mierda, generalmente, en java, que es cierto o que python o ruby no valgan, que no lo es.

    Yo preferiria programar en python las webs, pero java esta mucho mas extendido….

  25. @Blaxter
    No has usado Java en tu vida, estoy convencido de ello. Y ruby y phyton lo habrás buscado en google, para quedar bien aquí…

  26. Estoy iniciándome en el uso de framework para las aplicaciones Web por lo que este pequeño ejemplo me ayudó mucho y Gracias por eso… ademas de ser algo simple para muchos, creo yo que es mas valorado que una aplicación y/o sistema mucho mas elaborado debido al aporte que brinda

  27. jodo que panda de frikis… y además prepotentes, la peor mezcla que hay en el mundo de la informática. Blaster trankilo, tu no les sigas que no merece la pena, entre uno que se pone anonimo y otro MadreDelTopo, seguro que ni salen de casa y son de echarles de comer a parte. Ala! que sigais bien en vuestros mundos de frikilandia.

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.