Pero voy agradecer a Jose Diaz de Peru quien con su material que se encuentra disponible en la red me brindo una introducción a este framework que si bien tiene mucho tiempo en el mundo java nunca lo había tocado en detalle y gracias a esto quise conocerlo en profundidad y comenzó mi estudio sobre los beneficios de spring. Si bien trabaje con otros framework en java de verdad al estudiar Spring con profundidad te das cuenta la potencia del mismo para todo lo que un desarrollado puede llegar a necesitar en un proyecto.
Este Articulo forma parte de la guia creada en este sitio sobre Spring MVC.
Por definición:
"Como definir acciones en grupo en un solo controlador utilizando Annotation"
Desde ya hace algunas versión Spring permite el uso de un sistema de anotaciones que simplifica la forma de trabajar con el, logrando que el dispatchservlet pueda interpretar los mapeos sin necesidad de definirlo uno a uno en el spring bean configuration.
Amigos este es el mundo real en un proyecto grande lo vamos a hacer de esta forma, por que de esta forma no generamos grandes archivos de configuracion en spring, por que es un código mas limpio y por que es mas simple de leer e interpretar por los programadores...etc.
El MultiActionController en Spring nos permite controlar varias peticiones realizadas al servidor en una misma clase controlador, podemos interpretar, como su propio nombre indica, que un MultiActionController no es mas que un conjunto de Spring Controllers en una misma clase.
Donde esta la magia ?
El tema pasa primero por agregar la dependencia necesaria que posibilitara el scaneo de los controladores en nuestros paquetes.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
Segundo por definir las anotaciones en nuestro controlador que podremos entenderlo de una manera gráfica.
@Controller: Anotación que registra el controlador para Spring MVC, vamos utilizar esta Annotation en cada controlador que vamos a crear en nuestro proyecto.
@RequestMapping: Anotación que se encarga de relacionar un método con una petición http. Es decir cada uno de nuestros metodos del controlador deberá tener un mapeo con una URL de caso contrario no podria atender una solicitud de manera directa.
Nota: El uso de anotaciones no implica que únicamente tengamos un único controlador sino que nos permite agrupar un conjunto de urls que esten asociadas a nivel de negocio en un controlador especifico. La aplicación soportará n controladores.
Finalmente indicarle a spring en su archivo de configuracion que busque en un paquete las Annotation que definimos anteriormente.
<context:component-scan base-package="Mi paquete"/>
Nota: Con este linea le indicamos a spring que busque los controladores y mapeos en el paquete que yo defina.
Para nuestro ejemplo vamos a crear una controladora que responsa a las operaciones CRUD por ejemplo
- add
- delete
- update
- list
Como en todo los ejemplo solo utilizaremos una vista dado que no es el objeto de estudio, y por supuesto lo único que buscamos registrar es nuestro paso por los métodos del controlador y su interacción con una vista, motivo por lo que la logica de cada uno de estos métodos sera básico simplemente pasando un mensaje a la vista.
Buenisimo !!! ahora como hacemos esto. jajajaja
Pero como trabajamos con MVC
Inicia con un Request
Finaliza con Response
Cuando se envía una solicitud a la Spring Framework MVC la siguiente secuencia de los acontecimientos suceden.
El DispatcherServlet recibe por primera vez la solicitud.
La consulta a la DispatcherServlet Handler Mapping e invoca el controlador asociado a la solicitud.
El proceso regulador de la solicitud llamando a los métodos apropiados de servicio y devuelve un objeto ModeAndView a la DispatcherServlet.
El objeto ModeAndView contiene los datos del modelo y el nombre de vista.
El DispatcherServlet envía el nombre de la vista a un ViewResolver para encontrar la visión real de invocar.
Ahora, el DispatcherServlet pasará el modelo de objetos a la vista para hacer que el resultado.
La vista con la ayuda de los datos del modelo hará que el resultado de vuelta al usuario.
Paso 0: Definir nuestro proyecto y archivo POOM.
Definamos nuestro proyecto
El siguiente paso es definir nuestro archivo pom para la gestión de dependencias.
pom.xml: definiremos todas las librerías necesarias para trabajar con nuestro ejemplo.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.company</groupId> <artifactId>mvc_MultiActionControllerAnnotation</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>mvc_MultiActionControllerAnnotation Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <spring.version>3.0.5.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.1.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> </dependencies> <build> <finalName>mvc_MultiActionControllerAnnotation</finalName> </build> </project>
En esta ocacion no utilizaremos ninguna libreria rara, solo spring y las taglib para trabajar con JSP un poquito.
Paso 1: Definir el dispacher
web.xml: Primero debemos modificar nuestro archivo web.xml de base para definir el dispachservlet de spring y la locacion del spring bean configuration file.
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>Spring Web MVC Application</display-name> <servlet> <servlet-name>mvc-dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc-dispatcher</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> </web-app>
En este archivo lo que realizamos es mendiante
Luego mediante
Mediante
lo que pusimos en servlet-name + "-servlet.xml", por consiguiente si tuviera una definición como <servlet-name>mvc-dispatcher</servlet-name> la busqueda del archivo se realizaria a mvc-dispatcher-servlet.xml.
Por ultimo tendremos la definición de nuestro ContextLoaderListener es el encargado de inicializar todo el contexto del framework para el funcionamiento de la mecanica MVC.
Paso 2: Definir nuestro controlador
Para nuestro ejemplo vamos a definir 1 controlador muy simples con el cual vamos a trabajar para que pueda reconocer diferentes metodos desde spring bean configuration.
Como lo unico que intentamos es demostrar nuestros paso por los metodos definidos en el controlador, vamos a crear los diferentes metodos crud en la clase y la logica simplemente sera pasar un mensaje a la vista que indique que paso por el metodo.
Los métodos crud son estos y la definición del nombre te garantizo que lo vas a entender mucho mas adelante.
- add
- delete
- update
- list
Nota: ModelAndView es un objeto que vale la pena mirarlo mas a fondo por que tiene muchos metodos y formas de crearlo de acuerdo a nuestra necesidad.
En nuestro ejemplo en el contructor le mandamos el nombre de la vista JSP "PaginaRetorno" y luego con el metodo addObjetc le agregamos un valor a key de nombre msg. Esto no es magia de seguro nuestra vista PaginaRetorno debe contener la clave a la que hacemos referencia por que de caso contrario no va tirar en Tucumano "un loco que haces esto a lo que haces referencia no existe en la vista".
Nota son controladores muy simple solo pasamos a la vista en cada metodo una leyenda que corresponde a la operacion a la que atendimos.
com.company.controlador.CustomerController.java: definimos nuestro controlador.
package com.company.controlador; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.multiaction.MultiActionController; @Controller public class CustomerController { @RequestMapping("/customer/add.htm") public ModelAndView add(HttpServletRequest request, HttpServletResponse response) throws Exception { return new ModelAndView("PaginaRetorno", "msg","add() method"); } @RequestMapping("/customer/delete.htm") public ModelAndView delete(HttpServletRequest request, HttpServletResponse response) throws Exception { return new ModelAndView("PaginaRetorno", "msg","delete() method"); } @RequestMapping("/customer/update.htm") public ModelAndView update(HttpServletRequest request, HttpServletResponse response) throws Exception { return new ModelAndView("PaginaRetorno", "msg","update() method"); } @RequestMapping("/customer/list.htm") public ModelAndView list(HttpServletRequest request, HttpServletResponse response) throws Exception { return new ModelAndView("PaginaRetorno", "msg","list() method"); } }
Ahora de seguro notamos que en primera instancia la clase controladora lleva un Annotation @controller y que por cada metodo mapeamos el metodo a una url con @RequestMapping.
Avisaaa!! me quieres decir que con esto voy a poder escuchar en los métodos cuando realicen una solicitud URL como las que mapeamos ?
Sip cuando realicemos una llamada a estas URL vamos a escuchar por cada uno de estos metodos.
Nota Personal: Si te apaga la maquina y cuando levanta te olvidas que tenes un apache ya escuchando por el puerto 8080 y el tomcat no responde, por favor no demores minutos en pensar que la vida te engaño, fijate si no hay algun proceso ocupando el puerto en lugar de perder el tiempo. que Salame nooo ? jajaja. sisi apache estaba en 8080 motivo por el que tomcat nunca subio al puerto.
Pero volviendo a la nuestro vamos a poder escuchar por las siguientes URL asociadas a cada metodo de la siguiente forma.
http://localhost:8080/mvc_MultiActionControllerAnnotation/customer/add.htm
http://localhost:8080/mvc_MultiActionControllerAnnotation/customer/delete.htm
http://localhost:8080/mvc_MultiActionControllerAnnotation/customer/update.htm
http://localhost:8080/mvc_MultiActionControllerAnnotation/customer/list.htm
Paso 3: Definir nuestro Vista
src/main/webapp/WEB-INF/pages/PaginaRetorno.jsp: Es simplemente la vista que utilizamos para el ejemplo.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <body> <h1>Spring MVC Ejemplo</h1> <h2>${msg}</h2> </body> </html>
Primero que nada Vamos a usar la Librería Estandar JSP (JSP Standard Tag Library - JSTL) por lo que primero tenemos que comenzar incluyéndolas en nuestro pom.XML de caso contrario nuestro jsp se va romper por todos lados, las librerías usadas son:
Ojo ya que estamos hablemos de una buena practica en construir archivos JSP como la utilizacion de las taglibs va ser de moneda corriente en todo los jsp con los que vamos a trabajar, una buena practica es definir un archivo include.jsp como cabecera que tendra lo que sea necesario en todos los jsp que vamos a crear.
ejemplo de un include.jsp
<%@ page session="false"%>
una pagina ejemplo jsp que utilice esta buena practica seria
<%@ include file="/WEB-INF/views/include.jsp" %>
Pero de verdad nos fuimos por las ramas, de vuelta con nuestro ejemplo encontramos la clave ${msg} que es a la cual hicimos referencia desde nuestros controladores. Te das cuenta que esto no es magia!! para todo una linea de código.
Paso 4: Definir nuestro Spring Bean Configuration File
src/main/webapp/WEB-INF/mvc-dispacher-servlet.xml: me voy a contradecir un poco en mis comentarios, aqui es donde comienza la magia, por que definiendo los aspectos necesarios la maquina spring comienza a funcionar.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.company.controlador" /> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" > <property name="prefix"> <value>/WEB-INF/pages/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> </beans>
Pero no veo que definamos el handler que permite que dispatchservlet pueda interpretar los controladores y pueda mapear una URL.
Exacto!!
Con component-scan logramos este objetivo, si con esto buscara las Annotation en el paquete que le indicamos y posibilitara que el mecanismo spring escuche las solicitudes.
Como ultima opción y no menos importante es la definicion del ViewResolver que es utilizado por el controlador para realizar el redireccionamiento adecuado, en nuestra definicion le decimos que dentreo del directorio /pages vamos a encontrar nuestras vistas y van a ser de extencion jsp.
Paso 5: Entendiendo la ejecución
Para facilitar la prueba definimos un index que haga referencia a URL que posibiliten entender el mapeo que realizamos en el contenedor bean.
Primero ejecutemos en tomcat.
Tendremos una index que nos proporciona los link para visualizar los diferentes posibilidades que definimos en nuestro archivo de configuración.
Las siguientes imágenes en su URL podrán mostrarnos la ejecución de cada uno de los métodos que definimos en la clase controladora.
El código del proyecto lo puedes descargar desde aquí.
codigofuente.zip
Este comentario ha sido eliminado por el autor.
ResponderEliminarTodo muy bien explicado pero creo que te has equivocado al momento de colocar el link para descargar el proyecto, porque solo es texto :(, te agradeceria mucho si lo corriges porfavor y de antemano gracias por tomarte el tiempo de explicar el framework de Spring :D
ResponderEliminar