<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ include file="/WEB-INF/jsp/include.jsp" %> Internacionalización con Spring

MVC de Spring (I)

Ramiro Lago Bagüés (Enero 2008)


Introducción

Para aplicar el patrón MVC ya contamos con:

Pero necesitamos una capa de control, que se compone de:

Lo que devuelve cada controlador es un objeto del tipo ModelAndView. Este objeto se compone de:


Configuración: web.xml

Empezaremos con el clásico web.xml. En el que se empieza definiendo el Listener que ante el evento contextInitialized cargará el contexto de aplicación:


	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

La localización de los archivos de definición de contexto de aplicación se puede hacer por medio del parámetro contextConfigLocation. Si no se indica nada, Spring buscará un archivo con nombre applicationContext.xml en WEB-INF.


	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>WEB-INF/xyz.xml, WEB-INF/abc.xml</param-value>
	</context-param> 

Lo siguiente es señalar el servlet que actuará como controlador frontal:


	<servlet>
		<servlet-name>spring21</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>spring21</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>

Dos aspectos importantes de la configuración del DispatcherServlet:

  1. El nombre que se da al servlet-mapping no es casual. Spring buscará el archivo spring21-servlet.xml, que sirve para configurar el resto de controladores, viewResolvers, urlMappings, etc.


  2. El url-pattern indica los tipos de peticiones que aceptará, en nuestro ejemplo con las extensiones .do.

Configuración: spring-servlet.xml

A continuación interesa conocer la configuración básica de los servlets, en nuestro ejemplo utilizamos spring21-servlet.xml en WEB-INF, ya que el servlet-name de web.xml es spring21.


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<!--  Definición de contexto de aplicación para Controlador frontal y resto de controladores -->
<beans>
	<!-- Controlador de index (consulta, insert, etc) -->
	<bean id="indexController" class="com.controlador.IndexController">
		<property name="servicioCliente" ref="servicioCliente" />
	</bean>
	<!-- Controlador de index (borrar) -->
	<bean id="borrarController" class="com.controlador.BorrarController">
		<property name="servicioCliente" ref="servicioCliente" />
	</bean>

	<!--  Indico que las vistas se toman de /WEB-INF/jsp/ y que tendrán extensión jsp  -->
	<bean id="viewResolver"
			class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/WEB-INF/jsp/"/>
		<property name="suffix" value=".jsp"/>
	</bean>

	<!-- Las llamadas a .do se dirigen a su controlador correspondiente -->
    <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    	<property name="mappings">
			<value>
            	/inicio.do=indexController
            	/borrar.do=borrarController
			</value>
		</property>
	</bean>
</beans>

En nuestro ejemplo tenemos dos controladores. Uno que hace las inserciones, actualizaciones (update) y consultas; otro que hace el borrado. Lo veremos más adelante. Normalmente un formario está asociado a un controlador, señalando la asociación en el action del formulario. En nuestro ejemplo cada controlador tiene como atributo un bean servicioCliente, que es definido en el applicationContext.xml.

El viewResolver indica donde están las vistas (normalmente JSPs) que son invocadas por el controlador frontal. En el ejemplo las vistas se toman de /WEB-INF/jsp y tienen la extensión jsp.

El bean urlMapping indica el mapeo de peticiones y controladores. En nuestro ejemplo cada petición .do tiene su correspondiente bean controlador definido más arriba. Observar que esto debe ser coherente con los url-mapping del servlet frontal en el web.xml. Podriamos evidentemente usar otras extensiones, como *.html o *.form, o indicar un directorio (app/*.do) o varios (*/*.do).


Configuración: applicationContext.xml

Para terminar con esto de la configuración es necesario tener en cuenta el tradicional application context de Spring. En nuestro ejemplo se llama applicationContext.xml y está en WEB-INF; esto hace que (recordando lo que hemos dicho antes) no sea necesario utilizar contextConfigLocation en el web.xml:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans SYSTEM "spring-beans.dtd">

<!-- CUANDO HAYA CONEXION A INTERNET: -->
<!--
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
		xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			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-2.5.xsd
			http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
-->
<beans>
	<!-- Las propiedades del dataSource tienen como valor properties -->
	<bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName" value="${jdbc.driverClassName}"/>
		<property name="url" value="${jdbc.url}"/>
		<property name="username" value="${jdbc.username}"/>
		<property name="password" value="${jdbc.password}"/>
	</bean>
	<!-- El DAO que tiene como atributo el dataSource -->
	<bean id="DAOCliente" class="com.persistencia.DAOClienteSpring">
		<property name="dataSource" ref="dataSource"/>
	</bean>

	<!-- El Servicio de Cliente tiene como atributo el DAO -->
	<bean id="servicioCliente" class="com.servicio.ServicioCliente">
		<property name="dao" ref="DAOCliente"/>
	</bean>

	<!-- Las propiedades para el dataSource -->
	<bean id="propertyConfigurer"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
		        <value>WEB-INF/configuracion.properties</value>
			</list>
		</property>
	</bean>
</beans>

Algunas cosas que merece la pena destacar:

En resumen:


Secuencia de configuración inicial

Veamos la secuencia de acciones que se desencdenan cuando el servidor de aplicaciones inicializa la aplicación:

  1. El servidor de aplicaciones dispara el evento ContextInitilized.


  2. Este evento invoca al ContextLoaderListener (señalado en web.xml) y crea el contexto de aplicación (applicationContext.xml).


  3. Inicialización del servlet frontal (DispatcherServlet) y creación de su contexto (spring21-servlet.xml). Los dos contextos se unen.


  4. El controlador central busca e inicializa componentes como ViewResolver o HandlerMapping. Si no los encuentra, inicializa versiones por defecto.

Con esto la web ya está preparada para recibir peticiones.



Volver