domingo, 24 de noviembre de 2013

Spring MVC: Controlador MultiActionController

De una manera practica, es otro de los tantos tipos de controladores que podemos definir con la utilización de spring.

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"

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.

Lo primero es crear nuestra clase que extendera de la clase MultiActionController, luego establecemos los métodos de la clase, igual que crearíamos el handleRequest en un Controller, pero implementando todos los que queramos dándoles el nombre que nos interese.

Para nuestro ejemplo vamos a crear una controladora que responsa a las operaciones CRUD por ejemplo 

  • AddCustomer
  • deleteCustomer
  • updateCustomer
  • listCustomer

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_MultiActionController</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>mvc_MultiActionController 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_MultiActionController</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 definimos el dispatchservlet y el orden de prioridad para las solicitudes. La tarea de este recurso es procesar las llamadas realizadas a la aplicación y determinar que Controlador sera el encargado de atenderla para su resolución.

Luego mediante definimos el patron de filtro para la escucha de solicitudes si por ejemplo agregamos *.htm le estamos indicando que escuche todo las llamadas que hagan referencia a archivos htm.

Mediante definimos donde buscara el spring bean configuration file que utilizara nuestro proyecto. Ahora si esta información no es proporcionada en el archivo de analisis, spring por si solo buscara el archivo en WEB-INF  con el nombre resultante de una concatenacion simple.

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.
  • testaddCustomer
  • testdeleteCustomer
  • testupdateCustomer
  • testlistCustomer
Ahora estos metodo retorna un ModelAndView que como su nombre lo indica es una composicion del modelo logico de datos y vista o interfaz de usuario. En pocas palabras representa la vista y el modelo devueltos por un controlador al dispatchservlet, la vista toma la forma de una referencia a un objeto view o nombre de vista que por supuesto sera analizado y redireccionado por un ViewResolver. El modelo es un mapa, lo que permite el uso de múltiples objetos de datos con clave de nombre.

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.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

public class CustomerController extends MultiActionController{
 
 public ModelAndView testaddCustomer(HttpServletRequest request,
  HttpServletResponse response) throws Exception {
  
  return new ModelAndView("PaginaRetorno", "msg","add() method");
   
 }
 
 public ModelAndView testdeleteCustomer(HttpServletRequest request,
  HttpServletResponse response) throws Exception {
   
  return new ModelAndView("PaginaRetorno", "msg","delete() method");
    
 }
 
 public ModelAndView testupdateCustomer(HttpServletRequest request,
  HttpServletResponse response) throws Exception {
   
  return new ModelAndView("PaginaRetorno", "msg","update() method");
    
 }
 
 public ModelAndView testlistCustomer(HttpServletRequest request,
  HttpServletResponse response) throws Exception {
    
  return new ModelAndView("PaginaRetorno", "msg","list() method");
     
 }
 
}


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:




  • JSTL



  • TAGLIBS


  • 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"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

    una pagina ejemplo jsp que utilice esta buena practica seria 


    <%@ include file="/WEB-INF/views/include.jsp" %>
    <html>
      <head><title>Hello :: Spring Application</title></head>
      <body>
        <h1>Hello - Spring Application</h1>
        <p>Greetings, it is now <c:out value="${now}"/></p>
      </body>
    </html>

    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"
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
     
     <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />
        
        <bean class="com.company.controlador.CustomerController">
         <property name="methodNameResolver">
       <bean class="org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver">
        <property name="prefix" value="test" />
        <property name="suffix" value="Customer" />
       </bean>
      </property>
        </bean>
     
     
     <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>
    

    como primera instancia vamos a definir el handler que vamos a utilizar se llama ControllerClassNameHandlerMapping, ojo por que este es el que permite que dispatchservlet pueda interpretar que mediante un bean mapeamos una URL  a una controladora.

    Ahora el siguiente paso es por supuesto definir el bean para el controlador que en nuestro caso hace referencia al que definimos CustomerController, los siguiente es configurar la propiedad methodNameResolver que sera la que se encarga de establecer el método a ejecutar mediante la opción del parámetro que establezcamos.

    Ahora InternalPathMethodNameResolver es el que se encarga de resolver los metodos de acuerdo a patrones de URL y en nuestro caso utilizamos 2 propiedades

    • prefix = test   (por esto todo los metodos que definimos en el controlador comienzan con test)
    • suffix  = Customer  (por esto todo los metodos que definimos en el controlador terminan con customer)

    Recordemos
    • testaddCustomer
    • testdeleteCustomer
    • testupdateCustomer
    • testlistCustomer
    Ahora si!! todo comienza a tomar sentido, esto quiere decir que yo podre resolver las llamadas utilizando de  la siguiente forma 
    • add.htm
    • delete.htm
    • update.htm
    • list.htm

    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 podran mostrarnos la ejecución de cada uno de los metodos que definimos en la clase controladora.








    El código del proyecto lo puedes descargar desde aquí.

    codigofuente.zip



    Spring MVC: Entendiendo ControllerClassNameHandlerMapping

    De una manera practica, es otra forma de definir la forma en que serán expuesto nuestros controladores del proyecto.

    Este Articulo forma parte de la guia creada en este sitio sobre Spring MVC.

    Por definición:

    "Es la forma que podremos mapear un URL con el nombre del controlador en la definición en nuestro spring bean configuration file  o nuestro contenedor de beans."

    Nota: En la practica no es nada complicado, solo debemos definir el bean para ControllerClassNameHandlerMapping donde le definiremos algunas propiedades aplicadas a las llamadas como caseSensitive donde básicamente indico si es lo mismo con minúsculas y mayúsculas, pathPrefix que indica algún path fijo donde debería escuchar, entre otras posibilidades que existen.   Luego solo declaramos un bean por cada controlador y listo con esto ya tenemos el mapeo realizado. 

    En pocas palabras si nuestro controlador se llama WelcomeController yo podría referenciarlo como http...................../el pathPrefix que defini/welcome.htm y se generaría la magia donde dispatchservlet escucharía nuestra solicitud. 

    Para nuestro ejemplo en esta ocasión veremos como podemos mapear controladoras a una URL y acceder a ellas. Definimos 2 controladores y propiedades para definir la llamada, por ejemplo que solo se utilice minúsculas y un path como /customer en la llamada.

     mis controladores son 

    • HelloGuestController
    • WelcomeController


    y voy a definir un path implícito como /customer por lo que las llamadas deberían realizarce de la siguiente forma para que tengan respuesta.

    http://localhost:8080/mvc_ControllerClassNameHandlerMapping/customer/welcome.htm
    http://localhost:8080/mvc_ControllerClassNameHandlerMapping/customer/helloGuest.htm

    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_SimpleUrlHandlerMapping</artifactId>
      <packaging>war</packaging>
      <version>0.0.1-SNAPSHOT</version>
      <name>mvc_SimpleUrlHandlerMapping Maven Webapp</name>
      <url>http://maven.apache.org</url>
      <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>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
     </dependency>
      </dependencies>
      <build>
        <finalName>mvc_SimpleUrlHandlerMapping</finalName>
      </build>
      <properties>
       <spring.version>3.0.5.RELEASE</spring.version>
      </properties>
    </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 definimos el dispatchservlet y el orden de prioridad para las solicitudes. La tarea de este recurso es procesar las llamadas realizadas a la aplicación y determinar que Controlador sera el encargado de atenderla para su resolución.

    Luego mediante definimos el patron de filtro para la escucha de solicitudes si por ejemplo agregamos *.htm le estamos indicando que escuche todo las llamadas que hagan referencia a archivos htm.

    Mediante definimos donde buscara el spring bean configuration file que utilizara nuestro proyecto. Ahora si esta información no es proporcionada en el archivo de analisis, spring por si solo buscara el archivo en WEB-INF  con el nombre resultante de una concatenacion simple.

    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 2 controladores muy simples que luego los mapearemos en el spring bean configuration. 

    Si bien existen numerosos controladores en spring en esta oportunidad vamos a utilizar uno de los mas basicos para el ejemplo AbstractController. Todos los controladores que extienden de esta clase deben implementar el método handleRequestInternal(), que se ejecutará al ser invocado el controlador.

    Ahora este metodo retorna un ModelAndView que como su nombre lo indica es una composicion del modelo logico de datos y vista o interfaz de usuario. En pocas palabras representa la vista y el modelo devueltos por un controlador al dispatchservlet, la vista toma la forma de una referencia a un objeto view o nombre de vista que por supuesto sera analizado y redireccionado por un ViewResolver. El modelo es un mapa, lo que permite el uso de múltiples objetos de datos con clave de nombre.

    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". Se que voy a sonar como una madre diciendo ojo con el nombre de vista que ponemos que se tiene que corresponder con un JSP, pero de verdad es que los programadores somos muy extremos y cuando ocurra un error de que no encuentra el jsp vamos a pensar que esto no funciona bien que estamos manejando mal el framework...etc y vamos a pasar un buen rato hasta que nos demos cuenta que pusimos mal el nombre.

    Nota son controladores muy simple solo intentamos mostrar como mapear mas de un controlador.

    com.company.controlador.HelloGuestController.java: definimos nuestro controlador.

    package com.company.controlador;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.mvc.AbstractController;
    
    public class HelloGuestController extends AbstractController{
    
     @Override
     protected ModelAndView handleRequestInternal(HttpServletRequest request,
       HttpServletResponse response) throws Exception {
            System.out.println("paso");
      ModelAndView model = new ModelAndView("PaginaRetorno");
      model.addObject("msg", "Paso por Guest controlador");
      
      return model;
     }
    
    }
    


    com.company.controlador.WelcomeController.java: definimos nuestro controlador.

    package com.company.controlador;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.mvc.AbstractController;
    
    public class WelcomeController extends AbstractController{
    
     @Override
     protected ModelAndView handleRequestInternal(HttpServletRequest request,
       HttpServletResponse response) throws Exception {
    
      ModelAndView model = new ModelAndView("PaginaRetorno");
      model.addObject("msg", "Paso por Welcom controlador");
      
      return model;
     }
    
    }
    


    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:








  • JSTL







  • TAGLIBS


  • 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"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

    una pagina ejemplo jsp que utilice esta buena practica seria 


    <%@ include file="/WEB-INF/views/include.jsp" %>
    <html>
      <head><title>Hello :: Spring Application</title></head>
      <body>
        <h1>Hello - Spring Application</h1>
        <p>Greetings, it is now <c:out value="${now}"/></p>
      </body>
    </html>

    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"
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    
     <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
      <property name="caseSensitive" value="true" />
      <property name="pathPrefix" value="/customer" /> 
     </bean>
     
     <bean class="com.company.controlador.WelcomeController" />
     <bean class="com.company.controlador.HelloGuestController" />
     
     <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>
    

    como primera instancia vamos a definir el handler que vamos a utilizar y como lo dice el titulo en este caso se llama ControllerClassNameHandlerMapping, ojo por que este es el que permite que dispatchservlet pueda interpretar que mediante un bean mapeamos una URL  a una controladora.

    Dentro de las propiedades vamos a definir particularidades asociadas a la llamada de la solicitud, por ejemplo que necesitamos que distinga minuscula y mayuscula 


    <property name="caseSensitive" value="true" />

    Nota: con esto lo que indicamos que si nuestro controlador se llama WelcomeController nuestra llamada deberemos realizarla welcome.htm  es decir con minuscula la primera letra y sin el Controller. 

    Ahora queremos que las llamadas solo las escuchemos en un path definido como 

    <property name="pathPrefix" value="/customer" />

    Nota: con esto básicamente estamos indicando  el path padre contenedor de la llamada, por consiguiente resolverá el controlador por nombre en las llamadas cuyo directorio padre sea customer.

     Ejemplo 

    http://localhost:8080/mvc_ControllerClassNameHandlerMapping/customer/welcome.htm
    http://localhost:8080/mvc_ControllerClassNameHandlerMapping/customer/helloGuest.htm

    Lo siguiente es solo definir un bean por cada controlador.

    <bean class="com.company.controlador.WelcomeController" />

    <bean class="com.company.controlador.HelloGuestController" />

    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. 



    En el primero link podremos visualizar que hace referencia al controlador WelcomeController de la manera welcome.html dentro del path padre customer como lo indicamos en el ejemplo.




    El siguiente link hace referencia al controlador HelloGuestController de la manera url como helloGuest.htm dentro del path padre customer 




    El código del proyecto lo puedes descargar desde aquí.

    codigofuente.zip



    jueves, 21 de noviembre de 2013

    Libros Android + Ebook Android

    Hola en esta oportunidad pongo a disposición de ustedes una pequeña librería sobre desarrollo Android recopilada de la red con todo el sudor de mi frente. Si bien no lei todos estos libros son una libreria muy util de búsqueda cuando se esta desarrollando aplicaciones.



    Te paso los link todos en mega de cada libro 

    https://mega.co.nz/#!784WFD5Q!HbD621jFcyZVhxRkFOiCilGDGFVkPYglT2hM0l0AVXE







    martes, 19 de noviembre de 2013

    Spring MVC: Entendiendo SimpleUrlHandlerMapping

    De una manera practica, es otra forma de definir la forma en que serán expuesto nuestros controladores del proyecto.

    Este Articulo forma parte de la guia creada en este sitio sobre Spring MVC.

    Por definición:

    "Es la forma que podremos mapear un URL a un controlador en la definición de un bean en nuestro spring bean configuration file  o nuestro contenedor de beans."

    Nota: En la practica no es nada complicado, solo debemos definir para cada mapeo la correspondiente linea en nuestro contenedor de beans lo que si lo trasladamos a un proyecto real de seguro el archivo se va poner algo logar, en fin la idea es conocer una de las alternativas que nos proporciona el framework y que el juicio de valor real lo realice el programador en el uso. Te imaginas un proyecto real con 200 lineas que representan todo los mapeos del proyecto !!! naa el creador de spring le viene un paro cardíaco por que ya contamos con scaneo automatico ... jajaja 

    Para nuestro ejemplo en esta ocasion veremos como podemos mapear controladoras a una URL y acceder a ellas.

    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_SimpleUrlHandlerMapping</artifactId>
      <packaging>war</packaging>
      <version>0.0.1-SNAPSHOT</version>
      <name>mvc_SimpleUrlHandlerMapping Maven Webapp</name>
      <url>http://maven.apache.org</url>
      <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>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
     </dependency>
      </dependencies>
      <build>
        <finalName>mvc_SimpleUrlHandlerMapping</finalName>
      </build>
      <properties>
       <spring.version>3.0.5.RELEASE</spring.version>
      </properties>
    </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 definimos el dispatchservlet y el orden de prioridad para las solicitudes. La tarea de este recurso es procesar las llamadas realizadas a la aplicación y determinar que Controlador sera el encargado de atenderla para su resolución.

    Luego mediante definimos el patron de filtro para la escucha de solicitudes si por ejemplo agregamos *.htm le estamos indicando que escuche todo las llamadas que hagan referencia a archivos htm.

    Mediante definimos donde buscara el spring bean configuration file que utilizara nuestro proyecto. Ahora si esta información no es proporcionada en el archivo de analisis, spring por si solo buscara el archivo en WEB-INF  con el nombre resultante de una concatenacion simple.

    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 2 controladores muy simples que luego los mapearemos en el spring bean configuration. 

    Si bien existen numerosos controladores en spring en esta oportunidad vamos a utilizar uno de los mas basicos para el ejemplo AbstractController. Todos los controladores que extienden de esta clase deben implementar el método handleRequestInternal(), que se ejecutará al ser invocado el controlador.

    Ahora este metodo retorna un ModelAndView que como su nombre lo indica es una composicion del modelo logico de datos y vista o interfaz de usuario. En pocas palabras representa la vista y el modelo devueltos por un controlador al dispatchservlet, la vista toma la forma de una referencia a un objeto view o nombre de vista que por supuesto sera analizado y redireccionado por un ViewResolver. El modelo es un mapa, lo que permite el uso de múltiples objetos de datos con clave de nombre.

    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". Se que voy a sonar como una madre diciendo ojo con el nombre de vista que ponemos que se tiene que corresponder con un JSP, pero de verdad es que los programadores somos muy extremos y cuando ocurra un error de que no encuentra el jsp vamos a pensar que esto no funciona bien que estamos manejando mal el framework...etc y vamos a pasar un buen rato hasta que nos demos cuenta que pusimos mal el nombre.

    Nota son controladores muy simple solo intentamos mostrar como mapear mas de un controlador.

    com.company.controlador.HelloGuestController.java: definimos nuestro controlador.

    package com.company.controlador;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.mvc.AbstractController;
    
    public class HelloGuestController extends AbstractController{
    
     @Override
     protected ModelAndView handleRequestInternal(HttpServletRequest request,
       HttpServletResponse response) throws Exception {
            System.out.println("paso");
      ModelAndView model = new ModelAndView("PaginaRetorno");
      model.addObject("msg", "Paso por Guest controlador");
      
      return model;
     }
    
    }
    


    com.company.controlador.WelcomeController.java: definimos nuestro controlador.

    package com.company.controlador;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.mvc.AbstractController;
    
    public class WelcomeController extends AbstractController{
    
     @Override
     protected ModelAndView handleRequestInternal(HttpServletRequest request,
       HttpServletResponse response) throws Exception {
    
      ModelAndView model = new ModelAndView("PaginaRetorno");
      model.addObject("msg", "Paso por Welcom controlador");
      
      return model;
     }
    
    }
    


    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:




  • JSTL



  • TAGLIBS


  • 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"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

    una pagina ejemplo jsp que utilice esta buena practica seria 


    <%@ include file="/WEB-INF/views/include.jsp" %>
    <html>
      <head><title>Hello :: Spring Application</title></head>
      <body>
        <h1>Hello - Spring Application</h1>
        <p>Greetings, it is now <c:out value="${now}"/></p>
      </body>
    </html>

    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"
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    
     <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
      <property name="mappings">
       <value>
       /welcome.htm=welcomeController
       /*/welcome.htm=welcomeController
       /helloGuest.htm=helloGuestController
       </value>
      </property>
     </bean>
     
     <bean id="welcomeController" 
      class="com.company.controlador.WelcomeController" />
      
     <bean id="helloGuestController" 
      class="com.company.controlador.HelloGuestController" />
     
     <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>
    

    como primera instancia vamos a definir el handler que vamos a utilizar y como lo dice el titulo en este caso se llama SimpleUrlHandlerMapping, ojo por que este es el que permite que dispatchservlet pueda interpretar que mediante un bean mapeamos una URL  a una controladora.

    Dentro de la propiedad Mappings vamos a definir los mapeos como valores de la propiedad, donde podemos notar la siguiente particularidad.

    url = controlador

    bajo este logia agregamos 3 relaciones y donde podemos notar que podemos agrega comodines. 

    Como ultima opcion 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. 




    El primero hace referencia a uno de los mapeos que realizamos entre la la url de manera implicita y la controladora y podemos notar que basicamente lo unico que hizo es asignar al key que ya mencionamos una cadena desde la controladora y el resultado es la vista con la aplicacion del modelo logico.




    El siguiente link hace referencia a la utilización de comodin al escuchar peticiones para welcome.html de manera indistinta de donde venga, lo que quiere decir que escuchara todas las url que hagan referencia al archivo.  Si observamos en la ejecución hice referencia a una solicitud de un path que no existe y escucho y genero un resultado.




    El siguiente es igual que el primero con la diferencia que hace referencia a otro controlador.




    El código del proyecto lo puedes descargar desde aquí.

    codigofuente.zip