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. Muchísimas gracias por el manual, me ha venido muy bien. Las explicaciones del funcionamiento son muy buenas.

    A los que se meten con php, que parece que sólo conocen Java, decirles simplemente que no tienen ni puta idea de lo que se puede hacer con php.

    Yo me voy a poner a estudiar el uso de struts, pero lo tengo muy claro, el día de mañana usaré la tecnología más apropiada al proyecto que tenga que desarrollar.

  2. Está muy bien el manual… si tienes algo de idea de java. Me pasé una semana entera intentando hacer esto, como un idiota.
    Al final acabé abriendo el struts-2-blank.war, que viene de ejemplo, y conseguí hacerlo funcionar.

    Y eso que eres de los que mejor explican…

  3. @deckerix No sabes que dices, CodeIgniter es un Framework de Php muy poderoso.
    Creo que PHP es mas facil de utilizar y se usan menos archivos. Con Java necesitas miles de archivo para realizar una tarea.

  4. Saludos

    es la primera vez que uso struts y al correr el ejemplo me da el error de:
    _________________________________________________
    type Informe de estado

    mensaje

    descripción El recurso requerido () no está disponible.
    _________________________________________________

    Tengo una duda en el nombre del paquete del strut.xml
    ya ke dice algo de “mi-paquete” y yo estoy usando el paquete default que me genera el proyecto
    necesito cambiar el nombre ?

    jeje disculpen la ignorancia

  5. Saludos

    tengo una semana tratando este tema de los struts2, perooo ya llegue a un punto donde ninguno de los ejemplos corre en mi computadora

    el ultimo error arrojado es el de::

    GRAVE: Excepción arrancando filtro struts2
    java.lang.NoClassDefFoundError: javax/servlet/Filter

    eh buskado muchos ejemplos, me han pasando ejemplos que funcionan en otras maquinas pero en mi pc no funcioanan, no se si alguien me puede ayudar con el problemaa ??? 🙁

  6. Que buen ejemplo amigo =), oye una pregunta conoces algún manual o tutorial de structs 2 que empize desde cero que me puedas recomendar…Gracias =)

  7. Pingback: >Colección de Tutoriales de programación web

  8. Hola muchas gracias por el tutorial, muy entendible. Estoy iniciado en java web, yo llevo ya un tiempesito en java pero en aplicaciones de escritorio y puedo decir que quien programa en java se enamora de el.

  9. benas…estoy iniciandome en strust2 y quisiera alguna manual en castellano facil.si me lo pueden mandar al mail les estari agradecido. saludos

  10. Buenas, me ha gustado mucho el tutorial de struts2, es más, lo he seguido al pie de la letra para hacer mi primera aplicación con struts. Lo que pasa es que no consigo que llegue a funcionar, me sale el típico 404 cuando cargo la página, he probado a meter más librerias de struts para ver si asi funcionaba, pero sigue pasando lo mismo. Si pudieras aconsejarme que puede ir mal te lo agradecería.
    Un saludo

  11. Hola a todos!

    He seguido el tutorial, pero al ejecutar la web me dice:

    Estado HTTP 404 – /hola/
    ————————————————–
    type Informe de estado
    mensaje /hola/
    descripción El recurso requerido (/hola/) no está disponible.
    ————————————————–
    Apache Tomcat/7.0.25

    Utilizo struts-2.3.1.2 y apache-tomcat-7.0.25
    ¿Sabe alguien qué puede fallar?
    Saludos y gracias,

  12. Hola, esta muy bien el tutorial pero creo que si se complementara con mas pantallas y con la parte de la configuración de eclipse y tomcat, seria excelente. Ya que hay personas que apenas se inicia en menesteres.

  13. Pingback: Aplicaciones Strusts 2 Java netbeans | edwinxbmc

  14. Hola

    Primero que nada te felicito por tu tutorial, esta muy bien explicado, lamentablemente no me sale :s y pienso que es por que no se que indicar en mi name si coloque mi struts.xml y el Hola en el directorio raiz (java Resources:src)(osea no tengo paquete) y no se que colocar en:

    saludos!!!

  15. Hola

    Primero que nada te felicito por tu tutorial, esta muy bien explicado, lamentablemente no me sale :s y pienso que es por que no se que indicar en mi name si coloque mi struts.xml y el Hola en el directorio raiz (java Resources:src)(osea no tengo paquete) y no se que colocar en:

    saludos!!!

  16. Hola

    Primero que nada te felicito por tu tutorial, esta muy bien explicado, lamentablemente no me sale :s y pienso que es por que no se que indicar en mi name si coloque mi struts.xml y el Hola en el directorio raiz (java Resources:src)(osea no tengo paquete) y no se que colocar en el atributo name del tag Struts del archivo struts.xml

    saludos!!!

  17. No me iba pq me faltaban mas librerias. Estas son las que tengo para que funcione:

    commons-fileupload-1.2.2.jar
    commons-io-2.0.1.jar
    commons-lang3-3.1.jar
    commons-logging-1.1.1.jar
    freemarker-2.3.19.jar
    javassist-3.11.0.GA.jar
    ognl-3.0.6.jar
    struts2-core-2.3.8.jar
    xwork-core-2.3.8.jar

    Ademas, he cambiado el web.xml ya que FilterDispatcher está deprecated

    struts2
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

    struts2
    /*

  18. He programado en PHP y es demasiado fácil, ahora este Strut2 es todo un mundo con los Servlets, a mi parecer Servlet ya no debe existir, si quieres una aplicación rápida y con mucho menos código confuso utiliza ACTION’s nada mejor que combinar patron DAO con Action y Struts2 super sencillo y mejor manejo de DATA. Saludos

    1. Servlets siempre existira es como decir que no se para que existe el binario de echo por debajo struts invoca un servlet, incluso un jsp cuando se compila lo que se obtiene es como un servlet yo solo digo que java se ha convertido en un monstruo con chorrocientos mil ficheros que configurar en la que cualquier cosa puede salir mal y cuantos mas frameworks por medio mas facil es meter la pata

  19. Solo digo una cosa desarrollar casi cualquier cosa en java se tarda una eternidad abstraccion de abstraccion de abstraccion, al final te piensas que el framework es java y son formas de trabajo utilizando java, aprender casi un lenguaje o forma de hacer para que mañana cambien a otro framework me parece una perdida de tiempo para eso prefiero construirme el mio propio y lo utilizo donde me parece, al final es utilizar lo que ha echo otro por convencion y porque a la mayoria le parece bueno, no es reinventar la rueda es que en muchas ocasiones por no decir la mayoria es matar moscas a cañonazos para un desarrollo tonto que en cualquier otro lenguaje y/o plataforma tardaria un mes (Lotus Domino es la aplicacion origen) y Java/Struts es la aplicacion destino llevan en cierto lugar que no quiero mencionar 1 año y con errores es que en J2EE de toda la vida tardaria menos en hacerla otra cosa distinta es para aplicaciones grandes que si ayuda bastante

    Mejor ejemplo hacete un hola mundo en J2EE y otro con J2EE + Struts te cagas la de ficheros clases etc etc etc que tienes que crear

    Sigo pensando que para proyectos grandes puede que Struts y otros frameworks esten de perlas pero para proyectos medianos pequeños RubyRails va bastante mejor en cuanto a tiempo de desarrollo

    Tanto que se molestan en hacer un framework como struts muy potente y tal porque no hacen un ide basado en el que te lo de todo mascado? ya que es una forma de trabajo no deberia de ser complicado total lo que se quiere es aumentar tiempo de desarrollo reutilizando codigo no?

Deja un comentario

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