sábado, 16 de febrero de 2013

Conociendo Struts 2 - Armando mi primer Proyecto

En el anterior articulo aprendimos sobre el funcionamiento de struts  2, sus ventajas y desventajas, en esta ocasión buscaremos abordar en la practica como armar un proyectos en eclipse.

Si bien dentro de la carpeta lib de struts encontramos muchas librerías.



En esta ocasión utilizaremos las siguientes dado que por el momento estamos iniciando las practicas a manera que avancemos incorporaremos otras a nuestros ejemplos.


La información del objetivo de cada uno de estos jar de seguro se pueden encontrar en la red pero creo que es necesario brindar una pequeña reseña.

commons-fileupload: FileUpload analiza peticiones HTTP que se ajusten a la RFC 1867, "basada en formularios de carga de archivos en HTML". Es decir, si una petición HTTP se envía mediante el método POST, y con un tipo de contenido "multipart / form-data", entonces FileUpload puede analizar esa petición, y poner los resultados a disposición de forma fácilmente utilizado por la persona que llama.


commons-io: Commons IO es una biblioteca de utilidades para ayudar en el desarrollo de la funcionalidad de IO. Proporciona soporta para las operaciones de entrada y salida en general como escritura y lectura de archivos, gestión de filtros, comparación de archivos entre otras virtudes que por lo general todo proyecto struts 2 lo requiere.


commons-lang3: Lang ofrece una serie de servicios públicos de ayuda para la API de java.lang, en particular los métodos de manipulación de cadenas, métodos numéricos básicos, objeto de reflexión, la simultaneidad, la creación y la serialización y propiedades del sistema. 


commons-lang: lang3 es una version mas nueva de esta que utiliza otras clases, esta no es necesaria incluirla.


commons-logging: Apache Commons Logging (JCL) nos proporciona una Interfase cuyo propósito es ser una "abstracción" independiente de otros frameworks o toolkits de Logeo.

Por lo general se utiliza esta interfase en el código y después conectar una implementación en especifico (Log4J,Avalon LogKit , JDK 1.4 Logging API) a través de configuración sin necesidad de modificar el código. 

  1. import org.apache.commons.logging.Log;  
  2. import org.apache.commons.logging.LogFactory;  
  3. public class BasicLogging  {  
  4.    private static final Log LOGGER = LogFactory.getLog(BasicLogging.class);  


la cual puede ser utilizada de la siguiente forma en cualquier parte del código: 

LOGGER.info("Test de logging"); 

freemarker: FreeMarker es un "motor de plantillas", una herramienta genérica para generar la salida de texto (nada de HTML a código fuente generado automáticamente), basado en plantillas, está diseñado para ser práctico para la generación de páginas Web HTML, sobre todo por las aplicaciones basadas en servlets que utilizan el patron MVC (Model View Controller).


javassist: es una biblioteca de Java que proporciona un medio para manipular el código de bytes de Java de una aplicación.  En este sentido Javassist proporciona el soporte para  reflexión, es decir, la capacidad de cambiar la implementación de una clase en tiempo de ejecución.


ognl: significa Lenguaje Objeto-Graph Navigation, es un lenguaje de expresión para obtener y establecer las propiedades de los objetos de Java, además de otros extras como la proyección y la lista de selección y expresiones lambda. Se utiliza la misma expresión, tanto para obtener y establecer el valor de una propiedad.


struts2-core: ni hablar es el corazón de struts 2.


xwork-core: ni hablar el otro corazon de struts 2.


Nota: repasando en si esta son las dependencias que requiere struts para hacernos la vida fácil en el modelo de MVC que propone.


Primero creamos un proyecto dinámico en Eclipse: File à  New à Dynamic web Project




Nota: Le daremos el nombre en mi caso struts2_Ejemplo1 y por supuesto que lo enlazaremos a tomcat 7 que para esta etapa ya debería estar preparado y configurado, en caso contrario en el blog pueden encontrar una guia.

Ahora las carpetas que conforman mi proyecto y las que nos interesan en esta ocasión serán.



struts2_Ejemplo1\src : Directorio donde colocaremos las clases HolaMundo.java y en este caso el descriptor struts.xml.


Nota: como todo en java este framework struts utiliza un archivo de configuración llamado struts.xml y que por lo general deberemos colocarlo en la carpeta proyecto\src  en futuras entregas podremos notar que esto puede cambiar.


struts2_Ejemplo1\WebContent: Directorio donde colocaremos los JSP que para esta ocasión utilizaremos solo dos index.jsp y bienvenida.jsp.


struts2_Ejemplo1\WebContent\WEB-INF\  Directorio donde debería encontrar el descriptor de despliegue web.xml.


struts2_Ejemplo1\WebContent\WEB-INF\lib Directorio donde colocamos las librerías que usaremos de struts esta vez.

.
el resultado final debería ser algo como esto.




Mas claro imposible tenemos armada la estructura básica de mi primer proyecto struts, ahora vamos a trabajar en que esto pueda caminar.




























En primera instancia lo que debemos hacer es es indicar a Apache Tomcat que toda petición debe ser interceptada y gestionada por el filtro “FilterDispatcher”, el cual es el controlador de nuestra aplicación, para esto deberemos modificar el descriptor de despliegue web.xml.


<?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_3_0.xsd" id="WebApp_ID" version="3.0">

  <display-name>struts2_Ejemplo1</display-name>

  <filter>

   <filter-name>struts2</filter-name>

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

  </filter>

  <filter-mapping>

   <filter-name>struts2</filter-name>

   <url-pattern>/*</url-pattern>

  </filter-mapping>

  <welcome-file-list>

    <welcome-file>index.html</welcome-file>    

  </welcome-file-list>

</web-app>

Esta configuración es la más básica y por defecto para usar struts 2, podemos apreciar que se hace referencia al controlador (FilterDispatcher), el mapeo de las urls: /*, el cual indica al controlador que revise todas las peticiones (request) que envíe el cliente, y por último la página de inicio por defecto: index.html.

El siguiente paso es modificar el archivo de configuración de src\ struts.xml en donde estan las acciones a ejecutar por Struts 2.



<?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="default" extends="struts-default">



            <action name="holaMundo" class="actions.HolaMundo">

                  <result name="SUCCESS">/bienvenida.jsp</result>

            </action>

     

    </package>

</struts>

Dentro del paquete van las acciones, , la cual tiene los atributos básicos:name, el cual es el nombre de la acción a realizar, en este caso, cuando en la url termine en: holaMundo.action (notar que en el archivo struts.xml no viene ese nombre, no es necesario ya que struts es lo suficiente inteligente para mapearla), luego en este caso hay una clase en el atributo class que ejecutará la acción (Modelo, la clase Action), la cual tiene la Uri donde se encuentra:actions.HolaMundo. luego tenemos el resultado que se mostrará con el result al cliente en caso que sea exitosa la acción: <resultname="ok">/bienvenida.jsp</result>, esto nos dice que en caso de devolver la cadena (String) ok la acción (HolaMundo.java), nos envíe a la página: bienvenida.jsp



Las acciones son las encargadas de definir cual será la clase que se encargará de procesar la petición solicitada y cual será la respuesta dependiendo del resultado. Estas acciones se registran dentro de struts.xml.
La estructura básica de una acción es la siguiente:

   /pagina_error.jsp
   /pagina_exito.jsp
Nombre_Accion: identificador por el cual se llama a la accion desde la “Vista” (archivos JSP).
Paquete.Nombre_Clase: Controlador encargado de realizar la logica de la accion. Es una clase java, ubicada en algun paquete.
pagina_exito.jsp/pagina_error.jps: Son jsp’s que dependiendo si la respuesta del controlador serán visualizados.
Entonces, la logica desde el punto de vista de las acciones es la siguiente:
  • Se llama una acción (desde algún jps a struts.xml)
  • Se realiza la lógica (en alguna Clase)
  • La clase entrega un resultado (desde la Clase a struts.xml)
  • En función del resultado, se visualiza el jsp. ( desde struts.xml a jsp)
Ahora es el momento de hablar de los action, Struts 2  no te obliga a implementar ninguna interfaz o extiende de alguna clase, sólo es necesario para poner en práctica un método execute () que devuelve una cadena para indicar que la página de resultados debe devolver.
un ejemplo de esto seria 
package actions;

public class HolaMundo {

 public String execute() {
  return "success";
 }
 
}

pero struts 2 nos proporciona de manera opcional la posibilidad de implementar una interface que ayuda mucho a nivel código en cuanto a lógica de funcionamiento como.

package com.opensymphony.xwork2;
 
public interface Action {
 
    public static final String SUCCESS = "success";
 
    public static final String NONE = "none";
 
    public static final String ERROR = "error";
 
    public static final String INPUT = "input";
 
    public static final String LOGIN = "login";
 
    public String execute() throws Exception;
 
}
ahora si nuestra clase implementara esta interfaz.


el resultado por supuesto no es ni mas ni menos el que nosotros cremos en el codigo anterior respetando los requerimiento de struts 2 antes mencionados.


por lo que implementar la interface que nos proporciona el framework es de ayuda a que implementemos el método como nos indica o como lo necesita. 
Ahora tranquilos por que como pueden ver esto lo podemos hacer sin necesidad de implementar nada por lo que es algo que los programadores no tienden a usar mucho.

lo mas común es extender de ActionSupport que proporciona soporte para mensajes, acceso a propiedades, gestion de error y validación en si acceso a las acciones mas comunes a realizar en un action.



execute () - Este método ejecuta automáticamente cuando la acción se llama. Esta es la opción predeterminada  demostrando su lógica de negocio.

validate () - Este método es aplicado por defecto subclases método debe override este método para proporcionar validación.


ClearErrors () - Este método se puede utilizar cuando se quiere continuar con la ejecución, y quiere borrar el estado de la acción.


pausa () - Este método detiene / pausa la ejecución del método y devuelve inmediatamente la acción al resultado específico como Action.ERORR, Action.SUCCSESS, Action.INPUT. Cuando la próxima vez que esta acción es llamada se reanuda inmediatamente.


clearErrorsAndMessages () - Borra todos los mensajes de error y.


ClearErrors () - Borra todos los errores ().


clearMessages () - Borra todos los mensajes ().


ActionSupport clase también proporciona algunas LOG campos, textProvider,



NOTA FINAL: te quedo claro se usa para trabajar con action. 


por dios me la pase hablando de todo y nos fuimos de nuestro ejemplo de trabajo, por ello nosotros cuando creamos nuestra clase HolaMundo de seguro quedo algo asi.




bueno ahora vamos a agregar 1 propiedad de tipo string llamada Saludo


package actions;

public class HolaMundo {
  public String Saludo;   
}



llego la hora de generar nuestro pojo por lo que generamos los get y set para estas propiedades




El resultado final es 


ahora llega la parte interesante por que vamos a extender de la clase ActionSupport primero importamos la libreria necesaria y luego extendemos de la clase.



Nos presentara un conflicto por que no generamos un identificador serialversion


Desde el eclipse podremos generarlo sin problema.


Solucionado el problema aquí es donde nos encontramos



ahora no debemos olvidar la implementacion del método execute donde claramente llamaremos a un método e indicaremos el retorno donde struts.xml devuelve el resultado.



ahora tenemos que trabajar sobre las vistas donde en primera instancia vamos generar el contenido del archivo index.html.


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<META HTTP-EQUIV="Refresh" CONTENT="0;URL=holaMundo.action">

<title>Insert title here</title>

</head>

<body>

  <h3>Cargando...</h3>

</body>

</html>
 

Nota: como podemos observar el código html hace referencia a la llamada del action holaMundo que ejecutara la logica para proporcionar la salida en este caso un simple mensaje de saludo a la pagina resultante jsp.

y ahora vamos a editar el archivo bienvenida.jsp que debería quedar algo asi 


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

    pageEncoding="ISO-8859-1"%>

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

<!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>Insert title here</title>

</head>

<body>

      <h1><s:property value="Saludo" /></h1>

</body>

</html>
 

por ultimo deberíamos ejecutar sobre tomcat y el resultado seria 





y el resultado obtenido debería ser 



nuestro primer ejemplo de ejecución con struts2, perdón por hacer tan largo esta guía pero creí necesario tocar temas que en otro sitio se pasan por algo generando una dependencia solo mecánica sin entender el por que de las cosas.

En futuras entregas vamos a incrementar la complejidad del ejemplo que ayude a entender las virtudes de struts 2.

De por si me gustaría escuchar comentarios de parte de los lectores dado que es lo que ayuda a la transmisión del conocimiento el entender la otra parte, la que consume, aguardo comentarios.




6 comentarios:

  1. tengo este problema al ejecutar mi proyecto

    ant -f D:\\proyectos\\Proyecto_CieloAzul -DforceRedeploy=false -Ddirectory.deployment.supported=true -Dnb.wait.for.caches=true run
    init:
    deps-module-jar:
    deps-ear-jar:
    deps-jar:
    library-inclusion-in-archive:
    library-inclusion-in-manifest:
    compile:
    compile-jsps:
    Undeploying ...
    undeploy?path=/Proyecto_CieloAzul
    OK - Replegada aplicación en trayectoria de contexto /Proyecto_CieloAzul
    In-place deployment at D:\proyectos\Proyecto_CieloAzul\build\web
    Deployment is in progress...
    deploy?config=file%3A%2FC%3A%2FUsers%2Froi%2FAppData%2FLocal%2FTemp%2Fcontext658531242621860306.xml&path=/Proyecto_CieloAzul
    FALLO - Apliación desplegada en la ruta de contexto /Proyecto_CieloAzul, pero el contexto no pudo arrancar
    D:\proyectos\Proyecto_CieloAzul\nbproject\build-impl.xml:1046: The module has not been deployed.
    See the server log for details.
    BUILD FAILED (total time: 12 seconds)

    ResponderEliminar
    Respuestas
    1. Me suena a un problema con las dependencias o un tema de sintaxis en xml. pero me inclino por verificar si estan todas las librerias.

      Eliminar
  2. Hola como estas cuando ejecuto me sale esto porque pasa?

    Estado HTTP 404 - /struts2_ejemplo1/

    --------------------------------------------------------------------------------

    type Informe de estado

    mensaje /struts2_ejemplo1/

    descripción El recurso requerido no está disponible.


    --------------------------------------------------------------------------------

    Apache Tomcat/7.0.42

    ResponderEliminar
    Respuestas
    1. Hola, lograste solventar el problema expuesto? tengo varios días buscando una solución y no he podido. Creo que parte del problema es este mensaje: ago 08, 2015 9:16:31 PM org.apache.struts2.dispatcher.Dispatcher error. GRAVE: Dispatcher initialization failed.

      Se que mi servidor esta funcionando correctamente, las paginas web de jsp se ven correctamente sin struts2.

      Gracias por tu apoyo y orientación.

      Eliminar
  3. Unsando Struts2, Luego de realizar un insert, si vuelvo a refrescar la pagina se ejecuta nuevamnete el insert algiuen sabe porque???

    ResponderEliminar