Conociendo Spring MVC

En este post veremos de qué se trata el Spring MVC (como para descansar un poco de JSF). No es que sea JSF mejor que MVC ni viceversa. Sino es para conocer ambas propuestas. Además, en el nuevo Java EE 8 aparecerá un framework llamado MVC 1.0 que lucirá mucho al Spring MVC. (Igual que JPA a Hibernate)

Preparando el proyecto

Para comenzar, desde nuestro IDE favorito (NetBeans) crearemos un proyecto Maven web.


Y le ponemos las propiedades que tendrá nuestro proyecto

ProjectName:spring-mvc-store
GroupId: com.apuntesdejava
Package:com.apuntesdejava.spring.mvc.store



Y elegimos dónde queremos que se ejecute el proyecto. Yo voy a intentar ejecutar en Tomcat 8



Clic en "Finish" y ya estamos listos para comenzar.

Ahora, agregaremos la dependencia del Spring MVC
Podemos como cadena de búsqueda (campo query) el valor "spring-webmvc" y nos mostrará varios resultados. Seleccionaremos el que dice "org.springframework"

y clic en "Add"

Y, por la maravilla del Maven, se agregarán las bibliotecas faltantes.


Creando una página de bienvenida

Ahora, crearemos una página de bienvenida. Esta estará asociada a un controlador (porque debemos recordar lo que es el MVC). Así que crearemos primero nuestra vista (jsp) llamada "welcome.jsp" y lo colaremos en una subcarpeta de "Web Pages" llamada "jsp"



Y el contenido será el siguiente

<%-- 
    Document   : welcome
    Created on : Nov 24, 2014, 8:31:13 PM
    Author     : dsilva
--%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<title>Welcome</title>
</head>
<body>
  <section>
    <div class="jumbotron">
      <div class="container">
        <h1> ${greeting} </h1>
        <p> ${tagline} </p>
      </div>
    </div>
  </section>
</body>
</html>


Además, crearemos nuestra clase controladora en la carpeta "Source Packages"


package com.apuntesdejava.spring.mvc.store.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 *
 * @author dsilva
 */
@Controller
public class HomeController {
    @RequestMapping("/")
    public String welcome(Model model){
        model.addAttribute("greeting", "Bienvenido a la tienda virtual!");
        model.addAttribute("tagline", "Un aporte de apuntesdejava.com");
        return "welcome";
    }
    
}

Pegando todas las piezas con la clase DispatcherServlet

Hasta aquí ya tenemos las partes principales de la aplicación: la vista y la clase controladora. Pero aún la aplicación no funciona. Nos falta pegarlo todo con un Servlet que se encargará de recibir las peticiones del usuario y que lo distribuirá a las clases controladoras. Este servlet es org.springframework.web.servlet.DispatcherServlet

Siendo un servlet, este debe tener un nombre (claro) y el URL que deberá manejar. Como toda la aplicación web es todo el URL, lo que haremos será mapear desde la raiz ("/").

Así que -primero - crearemos el archivo web.xml desde el IDE.


Clic en Next y luego en Finish.

Al final, tendremos el editor con el siguiente contenido.

Podemos ir a la sección (botón superior) llamado "Servlets" y hacer clic en "Add Servlet Element...".

Y escribir los siguientes valores en los campos

Servlet nameDefaultServlet
Servlet classorg.springframework.web.servlet.DispatcherServlet
URL Pattern/


Clic en "OK"

Ahora, necesitamos crear el archivo DefaultServlet-servlet.xml en la misma carpeta donde se encuentra el archivo web.xml (es decir en WEB-INF)


Y el contenido es el siguiente:

<?xml version="1.0" encoding="UTF-8"?>
<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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
    
    <mvc:annotation-driven/>
    <context:component-scan base-package="com.apuntesdejava.spring.mvc.store"/>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>        
</beans>

(Quería hacerlo usando el asistente de NB para generar las etiquetas en base a un xmlns, pero no me salió, así que a copiar no más)

Lo ejecutamos, y saldrá esto


Y como estamos usando el Bootstrap, la página es responsive.


¿Cómo funciona esto?

  1. Cuando se llamó a la página, se está llamando a la raíz del contexto (en este caso, es /spring-mvc-store). Recordemos que hemos mapeado el servlet org.springframework.web.servlet.DispatcherServlet con el URL en la raíz (/)
  2. Ahora, el servlet buscará la configuración el archivo que termine con -servlet.xml en la carpeta WEB-INF. Este archivo .xml debe tener el mismo nombre del servlet. Es decir, el servlet que contenía a la clase DispatcherServlet tenía por nombre DefaultServlet, por tanto buscará al archivo DefaultServlet-servlet. Así de simple (por ahora)
  3. Este archivo .xml es el manejador de beans que utilizará el spring para instanciar los objetos. Analicemos este código: en la línea 11 le dice que se usará anotaciones de mvc, luego en la línea 12 dice que todas las clases que están en el paquete com.apuntesdejava.spring.mvc.store se les aplicará todas las anotaciones que tengan (en un rato más lo veremos). Y en el bean de la línea 13 es en sí el que se encargará de interpretar las peticiones y cómo deberá manejar los archivos de vista.
        <mvc:annotation-driven/>
        <context:component-scan base-package="com.apuntesdejava.spring.mvc.store"/>
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    
    ¿Cómo lo va hacer? Fácil: buscará todos los archivos que están dentro de /WEB-INF/jsp/ y que terminen con .jsp, de tal manera que si se le pide que llame a la página "lista-principal", este bean sabrá que se encuentra en /WEB-INF/jsp/lista-principal.jsp
  4. ¿Cómo llama a la clase HomeController? Porque allí tiene una anotación que está mapeada con "/", por tanto (línea 13). Spring sabe que esa clase es la controladora porque tiene la anotación @Controller.
    @Controller
    public class HomeController {
        @RequestMapping("/")
        public String welcome(Model model){
            model.addAttribute("greeting", "Bienvenido a la tienda virtual!");
            model.addAttribute("tagline", "Un aporte de apuntesdejava.com");        
            return "welcome";
        }
        
    }
    
  5. Ahora bien, tiene un método llamado "welcome" que está mapeado a la raíz. Por tanto, este método se ejecutará cuando se llame a la página raiz de la aplicación web. Este método debe devolver una String que será la página que quiere que se muestre al usuario. Además, el método tiene un parámetro de tipo org.springframework.ui.Model. Aquí estamos guardando los atributos que se usará en la vista (análogo a request.setAttribute de un servlet). Y terminamos con un return "welcome";
  6. Estos atributos que estamos guardando (greeting,tagline de las líneas 15 y 16 de la clase controladora) son los que se usarán en el archivo welcome.jsp, como ya se habrán dado cuenta hasta acá. Bastaría con ver las líneas 17 y 18 del jsp para que noten de qué se trata
        <div class="jumbotron">
          <div class="container">
            <h1> ${greeting} </h1>
            <p> ${tagline} </p>
          </div>
        </div>
    
Ahora, antes de terminar este primer post de Spring MVC: ¿cómo podemos poner el .xml en un lugar diferente al que está por omisión? Porque, como vimos en el punto 2, este debe ser el mismo nombre del servlet. Por ejemplo, supongamos que por orden lo pongamos dentro de una subcarpeta llamada spring/webcontext



Por tanto, debemos modificar un poco la configuración del servlet en nuestro archivo web.xml, agregando parámetros de inicialización


Hacemos clic en Add y agregamos los siguientes valores
Parameter namecontextConfigLocation
Parameter value/WEB-INF/spring/webcontext/DispatcherServlet-context.xml


El nombre del archivo .xml ya es arbitrario, el único requisito que debe cumplir es que esté bien configurado en el archivo web.xml

Es todo por ahora

Al menos estamos conociendo una alternativa más para crear aplicaciones web. 
El código fuente del proyecto que se mostró acá lo pueden descargar desde este link https://java.net/projects/apuntes/downloads/download/web/spring-mvc/spring-mvc-store.tar.gz

[Un día deberíamos hacer un proyecto interesante entre toda la comunidad para toda la comunidad, para hacer algo más agresivo y no hacer estos tutoriales de comprar perritos y gatitos, ¿no creen?]

Bibliografía

Para este (y los siguientes tutoriales) me he basado del siguiente libro que está bien interesante Spring MVC Beginner's.

[Quería hacer en un solo post todo el resumen del libro, pero - vamos - el tiempo lo tengo un poco limitado]

Si te gustó, hazlo saber.. y si crees que es útil, compártelo. Es gratis

Comentarios

  1. muy interesantes el tutorial pero lo malo es que no se puede descargar el proyecto

    ResponderBorrar

Publicar un comentario

Si quieres hacer una pregunta más específica, hazla en los foros que tenemos habilitados en Google Groups


Ah! solo se permiten comentarios de usuarios registrados. Si tienes OpenID, bienvenido! Puedes obtener su OpenID, aquí: http://openid.net/

Entradas más populares de este blog

UML en NetBeans

Cambiar ícono a un JFrame

RESTful... la forma más ligera de hacer WebServices (Parte 1)