Anda di halaman 1dari 78

Desarrollo de una aplicacin Spring

Framework MVC paso a paso


utilizando NetBeans y GlassFish
Autores
Thomas Risberg , Rick Evans , Portia Tung
Adaptado por Arulazi Dhesiaseelan para NetBeans / GlassFish

2.5
Las copias de este documento se pueden hacer para su propio uso y para su distribucin a
otros, siempre y cuando usted no carga ninguna cuota por las copias y que, adems de que
cada copia contenga este Aviso de copyright, ya sea distribuido en forma impresa o
electrnica.

Visin de conjunto
1. Qu est cubierto
2. Requisitos previos de software
3. La aplicacin que estamos construyendo
1. Aplicacin Bsico y Configuracin del entorno
1.1. Crear el proyecto de NetBeans Primavera
1.2. Crear 'index.jsp'
1.3. Desplegar la aplicacin de GlassFish
1.4. Compruebe funciona la aplicacin
1.5. Descargue el Spring Framework
1.6. Modificar 'web.xml' en el 'WEB-INF' directorio
1.7. Bibliotecas Copiar a 'WEB-INF / lib'
1.8. Cree el controlador
1.9. Escribe una prueba para el controlador
1.10. Cree la Vista
1.11. Compilar y desplegar la aplicacin
1.12. Pruebe la aplicacin
1.13. Resumen
2. El desarrollo y configuracin de las vistas y el controlador
2.1. Configure JSTL y aadir el archivo de cabecera JSP
2.2. Mejorar el controlador

2.3. Disociar la vista desde el controlador


2.4. Resumen
3. El desarrollo de la lgica de negocios
3.1. Revisar el modelo de negocio del Sistema de Gestin de Inventario
3.2. Aadir algunas clases de lgica de negocios
3.3. Resumen
4. El desarrollo de la Interfaz Web
4.1. Aadir referencia a la lgica de negocio en el controlador
4.2. Modificar la vista para mostrar los datos de negocio y aadir soporte para
mensaje paquete
4.3. Aadir algunos datos de prueba para rellenar automticamente algunos objetos
de negocio
4.4. Agregue el grupo de mensajes
4.5. Adicin de un formulario
4.6. Adicin de un controlador de forma
4.7. Resumen
5. Implementacin de persistencia de base de datos
5.1. Crear base de datos de secuencia de comandos de inicio
5.2. Crear tablas y secuencias de comandos de prueba de datos
5.3. Ejecutar secuencias de comandos y datos de ensayos de carga
5.4. Crear un objeto de acceso a datos (DAO) aplicacin para JDBC
5.5. Implementar pruebas para la aplicacin JDBC DAO
5.6. Resumen
6. La integracin de la aplicacin Web con la Capa de Persistencia
6.1. Modificar capa de servicio
6.2. Fijar las pruebas fallan
6.3. Crear nuevo contexto de aplicacin para la configuracin de capa de servicio
6.4. Aadir configuracin de transaccin y agrupacin de conexiones de contexto de
aplicacin
6.5. Prueba final de la solicitud completa
6.6. Resumen
A. Crear Scripts

Visin de conjunto
Este documento es una gua paso a paso sobre cmo desarrollar una aplicacin web
desde cero usando Spring Framework.

Slo se asume un conocimiento superficial de la misma primavera, y como tal, este


tutorial es ideal si usted est aprendiendo o la investigacin de la primavera.
Esperemos que el tiempo que ha trabajado su camino a travs del material tutorial
vers cmo las partes constituyentes de la Spring Framework, a saber Inversin de
Control (IoC), Aspect-Oriented Programming (AOP), y las diversas bibliotecas de
servicios Primavera (como la biblioteca JDBC) todos encajan en el contexto de una
aplicacin web Spring MVC.
Primavera ofrece varias opciones para configurar la aplicacin. El ms popular es el
uso de archivos XML. Esta es tambin la forma tradicional que ha sido apoyado
desde el primer lanzamiento de la primavera. Con la introduccin de Anotaciones en
Java 5, ahora tenemos una forma alternativa de configurar nuestras aplicaciones de
primavera. La nueva versin de Primavera 2.5 introduce un amplio soporte para el
uso de anotaciones para configurar una aplicacin web.
En

este

documento

se

utiliza

el

estilo

tradicional

de

XML

para

la

configuracin. Estamos trabajando en una "Anotacin Edition" de este documento y


esperamos publicarlo en un futuro prximo.
Tenga en cuenta que no vamos a cubrir cualquier informacin de fondo o la teora
en este tutorial; hay un montn de libros disponibles que cubren las reas de
profundidad; cada vez que se utiliza una nueva clase o funcin en el tutorial, se
proporcionan punteros hacia adelante a la seccin correspondiente (s) de la
documentacin de referencia de la primavera donde la clase o funcin se cubre en
profundidad.

1. Qu est cubierto
La lista siguiente detalla todas las diversas partes de la Spring Framework que
estn cubiertos en el transcurso del tutorial.

Inversin de Control (IoC)

El framework Spring Web MVC

Acceso a los datos con JDBC

Unidad e integracin de pruebas

Gestin de operaciones

2. Requisitos previos de software

Se

supone

que

el

siguiente

software

el

entorno

de

configuracin

prerrequisito. Tambin debe ser razonablemente cmodo utilizando las siguientes


tecnologas.

Java SDK 1.5 / 1.6

Ant 1.7

Primavera Netbeans Mdulo Release 1.1

GlassFish V2 UR1

NetBeans 6.0

NetBeans IDE 6.0 Pack Full (http://www.netbeans.org) ofrece un excelente


ambiente para el desarrollo de aplicaciones web. Los scripts de creacin Ant se
omiten en este debate, ya que son generados automticamente por el IDE. El
mdulo plugin de primavera para NetBeans se debe instalar antes del inicio de este
proyecto,
Usted puede por supuesto utilizar casi cualquier variacin o versin del software
anterior. Si desea utilizar IntelliJ lugar de NetBeans o embarcadero en lugar de
GlassFish, entonces muchos de los pasos del tutorial no se traducir directamente
en su entorno, sino que debe ser capaz de seguir a lo largo de todos modos.

3. La aplicacin que estamos construyendo


La aplicacin estaremos construyendo desde cero en el transcurso de este tutorial
es un muy bsico sistema de gestin de inventario. Este sistema de gestin de
inventario est severamente restringida en trminos de alcance; A continuacin te
presentamos un diagrama de casos de uso que ilustra los casos simples de uso que
estaremos implementando. La razn por la cual la aplicacin es tan limitado es para
que usted pueda concentrarse en los detalles de la primavera Web MVC y la
primavera, y no los detalles ms finos de la gestin de inventarios.

Utilice el diagrama caso del sistema de gestin de inventario


Vamos a empezar por la creacin de la estructura bsica de directorios del proyecto
para nuestra aplicacin, la descarga de las bibliotecas necesarias, la creacin de
nuestros scripts de construccin Ant, etc. El primer paso nos da una base slida
sobre la que desarrollar la aplicacin correcta de las piezas 2 , 3 , y 4 .
Una vez que la configuracin bsica est fuera del camino, s primavera se
introducir, a partir del framework Spring Web MVC. Usaremos la primavera Web
MVC para visualizar el stock inventariado, que involucrar a escribir algunas clases
de Java simples y algunas pginas JSP. Luego nos trasladaremos a la introduccin
de acceso a datos persistentes en nuestra aplicacin, utilizando el soporte de JDBC
simple de la primavera.
Por el momento hemos terminado todos los pasos del tutorial, vamos a tener una
aplicacin que hace la gestin del inventario bsico, incluyendo la lista de valores y
permitiendo el aumento de precios de este stock.

Captulo 1. Aplicacin Bsico y Configuracin


del entorno
1.1. Crear el proyecto de NetBeans Primavera

Vamos a necesitar un lugar para guardar toda la fuente y otros archivos estaremos
creando, as que vamos a crear un proyecto llamado 'springapp' . La decisin sobre
el lugar de crear este proyecto es totalmente de usted; Yo cre el mo en
un 'Proyectos' directorio que ya tena en mi 'Usuarios' directorio por lo que la ruta
completa en nuestro directorio del proyecto es ahora 'C: \ Users \ aruld \ Projects \
springapp' . Crear un nuevo proyecto Web desde Archivo -> Nuevo proyecto y haga
clic en Siguiente.

Proyecto Creacin Asistente: paso 1 de 3


Introduzca el nombre del proyecto como "springapp" y seleccione "GlassFish V2
UR1" como el servidor y haga clic en Siguiente.

Proyecto Creacin Asistente: Paso 2 de 3


Seleccione el marco como "Spring Framework 2.5" y escriba "springapp" como
nombre despachador y haga clic en Finalizar.

Proyecto Creacin Asistente: paso 3 de 3

Ponemos a tu disposicin una captura de pantalla de lo que su estructura de


directorios del proyecto debe ser similar despus de seguir las instrucciones
anteriores. (La captura de pantalla muestra la estructura de directorios del
proyecto en el IDE NetBeans: no es necesario utilizar el IDE NetBeans para
completar este tutorial con xito, pero utilizando NetBeans har que sea mucho
ms fcil seguir adelante.)

La estructura de directorios del proyecto

1.2. Crear

'index.jsp'

Desde que estamos creando una aplicacin web, vamos a empezar por actualizar la
pgina JSP bsica 'index.jsp' que consigui crear en el 'web' del directorio como
parte de la creacin del proyecto. El 'index.jsp' es el punto de partida para nuestra
aplicacin.
'Springapp / build / web / index.jsp' :
<Html>
<Head> <title> Ejemplo :: Primavera Aplicacin </ title> </ head>
<Body>
<h1> Ejemplo - Aplicacin de Primavera </ h1>
<P> Esta es mi prueba. </ P>
</ Body>

</ Html>
Slo

para

tener

una

aplicacin

web

completa,

vamos

actualizar

la 'web.xml' ubicado en 'WEB-INF' directorio dentro de la 'web' directorio con el


contenido se muestra a continuacin.
'Springapp / build / web / WEB-INF / web.xml' :
<? Xml version = "1.0" encoding = "UTF-8"?>
<Versin web-app = "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 ">
<Welcome-file-list>
<Welcome-file>
index.jsp
</ Welcome-file>
</ Welcome-file-list>
</ Web-app>

Haga clic en la ficha Archivos en el proyecto para ver el directorio web y su


contenido. archivos web.xml y index.jsp se encuentran en este directorio.

Proyecto Archivos Explorador

1.3. Desplegar la aplicacin de GlassFish


Haga clic derecho en el proyecto y haga clic en Generar. Se basa la aplicacin web.

Construir la aplicacin web


Haga clic derecho en el proyecto y haga clic en Deploy. Se despliega la aplicacin
Web en el servidor GlassFish.

Implementar la aplicacin web

1.4. Compruebe funciona la aplicacin


El servidor ya se ha iniciado cuando la aplicacin se despleg en el paso
anterior. Ahora puede abrir un navegador y vaya a la pgina de inicio de nuestra
aplicacin en la siguiente URL: http: // localhost: 8080 / springapp / index.jsp .

Pgina de inicio de la aplicacin

1.5. Descargue el Spring Framework


Si an no lo ha descargado el Spring Framework, ahora es el momento para
hacerlo. Actualmente estamos utilizando el 'Spring Framework 2.5' de liberacin
que

se

puede

descargar

desde http://www.springframework.org/download . Descomprimir este archivo en algn


lugar, ya que vamos a utilizar varios archivos desde este audio ms adelante.
Esto completa la configuracin del entorno que sea necesario, y ahora podemos
realmente empezar a desarrollar nuestra aplicacin Spring Framework MVC.

1.6. Modificar
Ir

la 'springapp

mnima 'web.xml' archivo

'web.xml'
build
que

en el
web

'WEB-INF'

directorio

WEB-INF' directorio. Modifique

actualizamos

antes. Vamos

la

definir

una DispatcherServlet(tambin conocido como 'Front Controller' (Crupi et al)). Se


va a controlar dnde todas nuestras peticiones se dirigen basan en la informacin
vamos a entrar en un momento posterior. Esta definicin servlet tambin tiene un
asistente <servlet-mapping /> entrada que se asigna a los patrones de URL que
vamos a utilizar.Hemos decidido dejar cualquier URL con un '.htm' extensin se
dirige a la 'springapp' servlet (el DispatcherServlet ).

'Springapp / web / WEB-INF / web.xml' :


<? Xml version = "1.0" encoding = "UTF-8"?>
<Versin web-app = "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 ">
<Servlet>
<Servlet-name> springapp </ servlet-name>
<Servlet-class> org.springframework.web.servlet.DispatcherServlet </
servlet-class>
<Load-on-startup> 1 </ load-on-startup>
</ Servlet>
<Servlet-mapping>
<Servlet-name> springapp </ servlet-name>
<Url-pattern> *. Htm </ url-pattern>
</ Servlet-mapping>
<Welcome-file-list>
<Welcome-file>
index.jsp
</ Welcome-file>
</ Welcome-file-list>
</ Web-app>
A continuacin, actualizar el archivo 'springapp-servlet.xml' situado en el 'springapp
/ build / web / WEB-INF' directorio. Este archivo contiene las definiciones de frijol
(objetos

antiguos

llanos

Java)

utilizados

por

el DispatcherServlet . Es

la WebApplicationContext donde todos los componentes relacionados con la web


van. El nombre de este archivo se determina por el valor de la <servletNombre

/> elemento

de

la 'web.xml' ,

con '-servlet' anexa

ella

(por

lo

tanto 'springapp-servlet.xml' ). Esta es la convencin de nomenclatura estndar


usada con Web framework MVC de Primavera. Ahora, agregue una entrada de frijol
llamado'/hello.htm' y especificar la clase como springapp.web.HelloController . Esto
define el controlador que nuestra aplicacin va a utilizar para dar servicio a una
peticin con el mapeo URL correspondiente de '/hello.htm' . El framework Spring
Web

MVC

utiliza

una

clase

de

implementacin

de

la

interfaz

llamadaHandlerMapping para definir la asignacin entre un URL de solicitud y el


objeto que se va a manejar esa peticin (el controlador). A diferencia de
laDispatcherServlet , el HelloController es responsable de manejar una solicitud de
una pgina en particular de la pgina web y tambin se conoce como
un'Controlador

Pgina' (Fowler). El

valor

predeterminado HandlerMapping que

el DispatcherServlet utiliza es el BeanNameUrlHandlerMapping ; esta clase utilizar


el

nombre

de

frijol

para

asignar

la

URL

en

el

pedido,

por

lo

que

el DispatcherServlet sabe qu controlador debe ser invocada para el manejo de


diferentes URL.
'Springapp / build / web / WEB-INF / springapp-servlet.xml' :
<? Xml version = "1.0" encoding = "UTF-8"?>
<frijoles 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 ">
<!

La

definicin

de

contexto

de

aplicacin

para

la

springapp

DispatcherServlet ->
<Nombre del bean = clase "/ hello.htm" = "springapp.web.HelloController" />
</ Beans>

1.7. Bibliotecas de primavera


Las bibliotecas de la primavera se copian cuando se cre por primera vez el
proyecto. Estos frascos sern desplegados en el servidor y que tambin se utilizan
durante el proceso de construccin.

Bibliotecas de la primavera

1.8. Cree el

controlador

Crea tu controlador de clase - estamos nombrarlo HelloController , y se define en


el 'springapp.web' paquete. Haga clic derecho en "Source Packages 'y crear una
clase Java 'HelloController.java' con el nombre del paquete 'springapp.web'.
'Springapp / src / java / springapp / web / HelloController.java' :
springapp.web paquete;
org.springframework.web.servlet.mvc.Controller importacin;
org.springframework.web.servlet.ModelAndView de importacin;
javax.servlet.ServletException importacin;
javax.servlet.http.HttpServletRequest importacin;
javax.servlet.http.HttpServletResponse importacin;
org.apache.commons.logging.Log importacin;
org.apache.commons.logging.LogFactory importacin;
java.io.IOException importacin;
public class HelloController implementa Controller {
registrador Iniciar ltima protegida = LogFactory.getLog (getClass ());
pblica

ModelAndView

handleRequest

(HttpServletRequest

request,

HttpServletResponse respuesta)
lanza ServletException, IOException {
logger.info ("Volviendo la vista hola");
volver nueva ModelAndView ("hello.jsp");
}
}
Este es un muy bsico Controller aplicacin. Estaremos ampliando esto ms
adelante, as como la ampliacin de algunas de las implementaciones de
controladores de base proporcionada por la primavera. En la primavera de Web
MVC, el controlador se encarga de la solicitud y devuelve una ModelAndView - en
este caso, uno nombrado 'hello.jsp' que es tambin el nombre del archivo JSP
crearemos siguiente. El modelo que devuelve esta clase se resuelve en realidad a
travs

de

unViewResolver . Puesto

que

no

hemos

definido

explcitamente

un ViewResolver , vamos a ser dado un defecto de uno en primavera que


simplemente remite a una direccin URL que coincida con el nombre de la vista
especificada. Vamos a modificar esta tarde. Tambin hemos especificado un
registrador para que podamos verificar que en realidad nos dieron en el manejador.

1.9. Escribe una prueba para el

controlador

Las pruebas son una parte vital del desarrollo de software. Tambin es una prctica
fundamental en el desarrollo Agile. Hemos encontrado que el mejor momento para
escribir pruebas es durante el desarrollo, y no despus, por lo que a pesar de que
nuestro controlador no contiene lgica compleja, vamos a escribir una prueba. Esto
nos permitir hacer cambios a la misma en el futuro con confianza. Vamos a utilizar
los "Paquetes de prueba 'para esto. Aqu es donde todas nuestras pruebas irn en
una estructura de paquete que reflejar el rbol de fuentes en 'springapp / src /
java' .
Crear una clase de prueba llamada 'HelloControllerTests' y hacer que se extienda
clase de prueba de JUnit TestCase . Es una prueba de unidad que verifica el nombre
de vista devuelta por handleRequest () coincide con el nombre de la vista se
espera: 'hello.jsp' .
'Springapp / test / springapp / web / HelloControllerTests.java' :
springapp.web paquete;
org.springframework.web.servlet.ModelAndView de importacin;
springapp.web.HelloController importacin;
junit.framework.TestCase importacin;
HelloControllerTests clase pblica se extiende TestCase {
public void testHandleRequestView () throws Exception {
Controlador HelloController = new HelloController ();
ModelAndView ModelAndView = controller.handleRequest (null, null);
assertEquals ("hello.jsp", modelAndView.getViewName ());
}
}
Podemos usar el IDE para ejecutar la prueba JUnit (y todas las pruebas que vamos
a escribir). Asegrese de que los frascos junit estn presentes en el lugar
'Bibliotecas de prueba' del proyecto.
Ahora ejecuta el JUnit haciendo clic derecho en el caso de prueba y seleccione
'Archivo Ejecutar "y la prueba debe pasar.

Ejecucin de prueba JUnit en el IDE


Otra de las mejores prcticas de desarrollo gil es integracin continua . Es una
buena idea para asegurarse de que sus pruebas se ejecutan con cada generacin
(lo ideal es que se basa el proyecto automatizado) de modo que usted sabe que su
lgica de la aplicacin se comporta como se esperaba ya que el cdigo evoluciona.

1.10. Cree la

Vista

Ahora es el momento de crear nuestra primera vista. Como hemos mencionado


anteriormente, le redireccionaremos a una pgina JSP llamado 'hello.jsp' . Para
empezar, vamos a poner en el 'web' del directorio.
'Springapp / build / web / hello.jsp' :
<Html>
<Head> <title> Hola :: Aplicacin primavera </ title> </ head>
<Body>
<H1> Hola - Aplicacin de Primavera </ h1>
<P> Saludos. </ P>
</ Body>
</ Html>

1.11. Compilar y desplegar la aplicacin


Consulte la seccin 1.3 para la construccin y despliegue de la aplicacin web desde
un IDE.

1.12. Pruebe la aplicacin


Vamos a tratar de esta nueva versin de la aplicacin.
Abra un navegador y vaya a http: // localhost: 8080 / springapp / hello.htm .

La aplicacin actualizada

1.13. Resumen
Echemos vistazo rpido a las partes de nuestra aplicacin que hemos creado hasta
ahora.

Una pgina de introduccin, 'index.jsp' , la pgina de bienvenida de la

aplicacin. Fue

utilizado

para

probar

nuestra

configuracin

es

correcta. Despus nos vamos a cambiar esta realidad para proporcionar un


enlace en nuestra aplicacin.

Un DispatcherServlet (controlador

frontal)

con

el

correspondiente 'springapp-servlet.xml' archivo de configuracin.

Un controlador de pgina, HelloController , con funcionalidad limitada -

slo devuelve un ModelAndView . Actualmente contamos con un modelo


vaco y estaremos proporcionando un modelo completo ms adelante.

Una

clase

de

prueba

de

unidad

para

el

controlador

de

la

pgina, HelloControllerTests , para verificar el nombre de la vista es el que


esperamos.

Un punto de vista, 'hello.jsp' , que de nuevo es extremadamente

bsico. La buena noticia es que el conjunto de las obras de instalacin y que


ahora est listo para aadir ms funcionalidad.
Ponemos a tu disposicin una captura de pantalla de lo que su estructura de
directorios del proyecto debe ser similar despus de seguir las instrucciones
anteriores.

La estructura de directorios del proyecto al final de la parte 1

Captulo 2. Desarrollo y configuracin de las


vistas y el controlador
Esta es la parte 2 de un tutorial paso a paso sobre cmo desarrollar una aplicacin
web desde cero usando Spring Framework. En la Parte 1 hemos configurado el
entorno y establecer una aplicacin bsica que ahora vamos a profundizar en.
Esto es lo que hemos puesto en marcha hasta el momento:

Una pgina de introduccin, 'index.jsp' , la pgina de bienvenida de la

aplicacin. Fue

utilizado

para

probar

nuestra

configuracin

es

correcta. Despus nos vamos a cambiar esta realidad para proporcionar un


enlace en nuestra aplicacin.

Un DispatcherServlet (controlador

frontal)

con

el

correspondiente 'springapp-servlet.xml' archivo de configuracin.

Un controlador de pgina, HelloController , con funcionalidad limitada -

slo devuelve un ModelAndView . Actualmente contamos con un modelo


vaco y estaremos proporcionando un modelo completo ms adelante.

Una

clase

de

prueba

de

unidad

para

el

controlador

de

la

pgina, HelloControllerTests , para verificar el nombre de la vista es el que


esperamos.

Un punto de vista, 'hello.jsp' , que de nuevo es extremadamente

bsico. La buena noticia es que el conjunto de las obras de instalacin y que


ahora est listo para aadir ms funcionalidad.

2.1. Configure JSTL y aadir el archivo de


cabecera JSP
Vamos a utilizar la JSP Standard Tag Library (JSTL), as que vamos a asegurarnos
de jstl.jar y standard.jar existen en 'Bibliotecas' directorio.
Vamos a crear un archivo de 'cabecera' que se incluye en cada pgina JSP que
vamos a escribir. Aseguramos las mismas definiciones se incluyen en todas nuestras
pginas JSP simplemente incluyendo el archivo de cabecera. Tambin vamos a
poner todas las JSP en un directorio llamado 'jsp' bajo el 'WEB-INF'directorio. Esto
asegurar que las opiniones slo se puede acceder a travs del controlador, ya que
no ser posible acceder a estas pginas directamente a travs de una URL. Esta
estrategia podra no funcionar en algunos servidores de aplicaciones y si este es el

caso con la persona que est usando, mueva el 'jsp' directorio de un nivel. A
continuacin,

utilice 'springapp

web

jsp' como

el

directorio

en

lugar

de 'springapp / web / WEB-INF / jsp' en todos los ejemplos de cdigo que seguirn.
En primer lugar vamos a crear el archivo de cabecera para su inclusin en todas las
pginas JSP que creamos.
'Springapp / build / web / WEB-INF / jsp / include.jsp' :
<% @ Sesin page =% "false">
<% @ Taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core"%>
<% @ Taglib prefijo = "fmt" uri = "http://java.sun.com/jsp/jstl/fmt"%>
Ahora podemos actualizar 'index.jsp' para utilizar este archivo de inclusin y ya que
estamos utilizando JSTL, podemos utilizar el <c: redirigir /> etiqueta para volver a
dirigir

nuestro

frente Controller . Esto

significa

que

todas

las

solicitudes

de 'index.jsp' pasar a travs de nuestro marco de aplicacin. Simplemente elimine


el contenido actual de 'index.jsp' y sustituirlo por el siguiente:
'Springapp / build / web / index.jsp' :
<% @ Include file = "/ WEB-INF / jsp / include.jsp"%>
<% - Redirigido porque no podemos establecer la pgina de bienvenida a
una URL virtual. -%>
<C: redirigir url = "/ hello.htm" />
Mover 'hello.jsp' a la 'WEB-INF / jsp' directorio. Aadir la misma directiva include
hemos aadido a 'index.jsp' a 'hello.jsp' . Tambin vamos a aadir la fecha y la hora
actual como la salida a recuperarse desde el modelo pas a la vista que se
representa utilizando el JSTL <c: out /> etiqueta.
'Springapp / build / web / WEB-INF / jsp / hello.jsp' :
<% @ Include file = "/ WEB-INF / jsp / include.jsp"%>
<Html>
<Head> <title> Hola :: Aplicacin primavera </ title> </ head>
<Body>
<H1> Hola - Aplicacin de Primavera </ h1>
<P> Saludos, ahora es <c: Fuera value = "$ {} ahora" /> </ p>
</ Body>
</ Html>

2.2. Mejorar el controlador


Antes de que actualizamos la ubicacin del JSP en nuestro controlador, vamos a
actualizar nuestra clase de prueba de unidad primero. Sabemos que tenemos que
actualizar la referencia de recursos de la vista con su nueva ubicacin 'WEB-INF /
jsp / hello.jsp' . Sabemos tambin debe haber un objeto en el modelo asignado a la
tecla "ahora" .
'Springapp / pruebas / HelloControllerTests.java' :
springapp.web paquete;
org.springframework.web.servlet.ModelAndView de importacin;
springapp.web.HelloController importacin;
junit.framework.TestCase importacin;
HelloControllerTests clase pblica se extiende TestCase {
public void testHandleRequestView () throws Exception {
Controlador HelloController = new HelloController ();
ModelAndView ModelAndView = controller.handleRequest (null, null);
assertEquals

("WEB-INF

jsp

hello.jsp",

modelAndView.getViewName ());
assertNotNull (modelAndView.getModel ());
Cadena nowValue = (String) modelAndView.getModel () conseguir
("ahora.");
assertNotNull (nowValue);
}
}
A continuacin, se corre el JUnit haciendo clic derecho en el caso de prueba y
seleccionamos 'Archivo Ejecutar' y la prueba debe fallar.

Ejecucin de prueba JUnit en el IDE


Ahora actualizamos HelloController estableciendo referencia de recursos de la vista
a su nueva ubicacin 'WEB-INF / jsp / hello.jsp' , as como establecer el par clave /
valor de la fecha actual y el valor del tiempo en el modelo con el identificador de
clave: " ahora " y el valor de cadena: 'ahora' .
'Springapp / src / java / springapp / web / HelloController.java' :
springapp.web paquete;
org.springframework.web.servlet.mvc.Controller importacin;
org.springframework.web.servlet.ModelAndView de importacin;
javax.servlet.ServletException importacin;
javax.servlet.http.HttpServletRequest importacin;
javax.servlet.http.HttpServletResponse importacin;
org.apache.commons.logging.Log importacin;
org.apache.commons.logging.LogFactory importacin;
java.io.IOException importacin;
java.util.Date importacin;
public class HelloController implementa Controller {
registrador Iniciar ltima protegida = LogFactory.getLog (getClass ());
pblica

ModelAndView

handleRequest

(HttpServletRequest

HttpServletResponse respuesta)
lanza ServletException, IOException {
Cadena ahora = (new Date ()) toString ().;

request,

logger.info ("Volviendo la vista hola con" + ahora);


volver nueva ModelAndView ("WEB-INF / jsp / hello.jsp", "ahora",
ahora);
}
}
Nos volver a ejecutar nuestra JUnit y pasa la prueba.
Recuerde

que

el controlador ya

se

ha

configurado

en 'springapp-

servlet.xml' archivo, por lo que estn dispuestos a probar nuestros mejoras


despus de crear e implementar este nuevo cdigo. Cuando entramos en http: //
localhost: 8080 / springapp / en

un navegador, debe levantar el archivo de

bienvenida 'index.jsp' , que debera redirigir a 'hello.htm' y es manejado por


el DispatcherServlet , que a su vez delega nuestra peticin al controlador de la
pgina que pone la fecha y hora en el modelo y luego hace que el modelo
disponible a la vista 'hello.jsp' .

La aplicacin actualizada

2.3. Disociar la vista desde el controlador


En este momento el controlador especifica la ruta completa de la vista, lo que crea
una dependencia innecesaria entre el controlador y la vista. Idealmente nos
gustara asignar a la vista con un nombre lgico, lo que nos permite cambiar la
vista sin tener que cambiar el controlador. Puede establecer esta asignacin en un

archivo

de

propiedades

si

te

gusta

usar

un ResourceBundleViewResolver y SimpleUrlHandlerMapping clase. Para el mapeo


bsico de una vista a una ubicacin, basta con establecer un prefijo y un sufijo en
el InternalResourceViewResolver . Este segundo enfoque es el que vamos a
implementar ahora, para que modificamos el 'springapp-servlet.xml' y declaramos
una 'ViewResolver' entrada. Al elegir el JstlView , que nos permitir utilizar JSTL en
combinacin con paquetes de recursos de mensajes, as como proporcionarnos el
apoyo a la internacionalizacin.
'Springapp / build / web / WEB-INF / springapp-servlet.xml' :
<? Xml version = "1.0" encoding = "UTF-8"?>
<frijoles 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.0.xsd ">
<! - La definicin de contexto de aplicacin para la DispatcherServlet
springapp ->
<Nombre del bean = clase "/ hello.htm" = "springapp.web.HelloController" />
<Bean

id

clase

"ViewResolver"

"org.springframework.web.servlet.view.InternalResourceViewResolver">
<Propiedad

nombre

valor

"viewClass"

"org.springframework.web.servlet.view.JstlView"> </ property>


<Propiedad nombre = valor "prefijo" = "/ WEB-INF / jsp /"> </
property>
<Propiedad nombre = valor "sufijo" = ". Jsp"> </ property>
</ Bean>
</ Beans>
Actualizamos

el

nombre

de

la

vista

controlador HelloControllerTests a 'hola' y

en

vuelva

la
a

clase
ejecutar

de
la

prueba
prueba

comprobar que falle.


'Springapp / test / springapp / web / HelloControllerTests.java' :
springapp.web paquete;
org.springframework.web.servlet.ModelAndView de importacin;
springapp.web.HelloController importacin;
junit.framework.TestCase importacin;
HelloControllerTests clase pblica se extiende TestCase {
public void testHandleRequestView () throws Exception {
Controlador HelloController = new HelloController ();
ModelAndView ModelAndView = controller.handleRequest (null, null);
assertEquals ("hola", modelAndView.getViewName ());

del
para

assertNotNull (modelAndView.getModel ());


Cadena nowValue = (String) modelAndView.getModel () conseguir ("ahora.");
assertNotNull (nowValue);
}
}
Entonces nos quitamos el prefijo y el sufijo del nombre de la vista en el controlador,
dejando el controlador para hacer referencia a la vista por su nombre lgico"hola".
'Springapp / src / java / springapp / web / HelloController.java' :
springapp.web paquete;
org.springframework.web.servlet.mvc.Controller importacin;
org.springframework.web.servlet.ModelAndView de importacin;
javax.servlet.ServletException importacin;
javax.servlet.http.HttpServletRequest importacin;
javax.servlet.http.HttpServletResponse importacin;
org.apache.commons.logging.Log importacin;
org.apache.commons.logging.LogFactory importacin;
java.io.IOException importacin;
java.util.Date importacin;
public class HelloController implementa Controller {
registrador Iniciar ltima protegida = LogFactory.getLog (getClass ());
pblica

ModelAndView

handleRequest

(HttpServletRequest

request,

HttpServletResponse respuesta)
lanza ServletException, IOException {
Cadena ahora = (new Date ()) toString ().;
logger.info ("Volviendo la vista hola con" + ahora);
volver nueva ModelAndView ("hola", "ahora", ahora);
}
}
Vuelva a ejecutar la prueba y ahora debe pasar.
Vamos a compilar y desplegar la aplicacin y verificar la aplicacin sigue
funcionando.

2.4. Resumen
Echemos vistazo rpido a lo que hemos creado en la Parte 2.

Un archivo de cabecera 'include.jsp' , la JSP que contiene las directivas

taglib para las bibliotecas de cdigos que usaremos en nuestras pginas JSP.
Estos son los artefactos existentes que hemos cambiado en la parte 2.

Los HelloControllerTests se ha actualizado varias veces a medida que

hacemos el controlador de referencia el nombre lgico de una vista en lugar


de su nombre codificado y la ubicacin.

El controlador de la pgina, HelloController , ahora hace referencia a la

vista

por

su

lgica

nombre

de

la

vista

travs

del

uso

de

la'InternalResourceViewResolver' definido en 'springapp-servlet.xml' .


Ponemos a tu disposicin una captura de pantalla de lo que su estructura de
directorios del proyecto debe ser similar despus de seguir las instrucciones
anteriores.

La estructura de directorios del proyecto al final de la parte 2

Captulo 3. Desarrollo de la lgica de negocios


Esta es la parte 3 de un tutorial paso a paso sobre cmo desarrollar una aplicacin
de Primavera. En esta seccin, vamos a adoptar un enfoque pragmtico Test-Driven
Development (TDD) para la creacin de los objetos de dominio y la aplicacin de la
lgica de negocio para nuestro sistema de gestin de inventario . Esto significa que

vamos a "codificar un poco, probar un poco, un poco ms de cdigo a continuacin,


probar un poco ms". En la Parte 1 hemos configurado el entorno y establecer una
aplicacin bsica. En la Parte 2 refinamos la aplicacin desacoplando la vista desde
el controlador.
La primavera est en hacer las cosas simples y fciles las cosas difciles posible. El
constructo fundamental que hace esto posible es el uso de la primavera de Plain Old
Java Objects (POJO). POJOs son esencialmente llano viejas clases Java gratis desde
cualquier contrato generalmente forzada por una arquitectura marco o componente
a travs de subclases o la implementacin de interfaces. POJOs son objetos
antiguos de civil que estn libres de estas limitaciones, por lo que la programacin
orientada a objetos es posible una vez ms. Cuando se trabaja con la primavera,
los objetos de dominio y servicios implementados sern POJOs. De hecho, casi todo
lo que implemente debe ser un POJO. Si no es as, usted debe estar seguro que
preguntarse por qu. En esta seccin, vamos a empezar a ver la sencillez y el poder
de la primavera.

3.1. Revisar el modelo de negocio del Sistema


de Gestin de Inventario
En nuestro sistema de gestin de inventario, tenemos el concepto de un producto y
un servicio para el manejo de ellos. En particular, la empresa ha solicitado la
posibilidad de aumentar los precios en todos los productos. Cualquier disminucin
se har sobre una base producto individual, pero esta caracterstica se encuentra
fuera del alcance de nuestra aplicacin. Las reglas de validacin para aumento de
precios son los siguientes:

El aumento mximo se limita al 50%.

El incremento mnimo debe ser mayor que 0%.

Ponemos a tu disposicin un diagrama de clases de nuestro sistema de gestin de


inventario.

El diagrama de clases para el sistema de gestin de inventario

3.2. Aadir
negocios

algunas

clases

de

lgica

de

Ahora vamos a aadir un poco de lgica de negocio en la forma de un producto de


clase y un servicio llamado ProductManager servicio que se encargar de todos los
productos. Con el fin de separar la lgica dependiente web desde la lgica de
negocio, colocaremos clases relacionadas con la capa web de la 'web' del paquete y
crear dos nuevos paquetes: uno para objetos de servicio denominadas "servicio" y
otro para los objetos de dominio llamado "dominio ' .
Primero implementamos el Producto clase como un POJO con un constructor por
defecto (siempre de forma automtica si no se especifica ningn constructor) y
captadores y definidores por sus propiedades 'descripcin' y 'precio' . Tambin
vamos a hacer es Serializable , no es necesario para nuestra aplicacin, pero podra
ser til ms adelante, cuando persistimos y almacenar su estado. La clase es un
objeto de dominio, por lo que pertenece en el 'dominio' paquete.
'Springapp / src / java / springapp / dominio / Product.java' :
springapp.domain paquete;
java.io.Serializable importacin;
clase Product pblica implementa Serializable {
Descripcin private String;

Precio Doble privado;


public String getDescription () {
Descripcin de vuelta;
}
public void setDescription (descripcin String) {
this.description = descripcin;
}
Doble getPrice pblica () {
Precio regresar;
}
pblica setPrice void (Precio Doble) {
this.price = precio;
}
public String toString () {
Tampn StringBuffer = new StringBuffer ();
buffer.append ("Descripcin:" + Descripcin + ";");
buffer.append ("Precio:" + precio);
volver buffer.toString ();
}
}
Ahora escribimos las pruebas unitarias para nuestro producto de clase. Algunos
desarrolladores no se molestan en pruebas de escritura para captadores y
definidores o llamado cdigo 'auto-generada ". Por lo general toma mucho ms
tiempo para participar en el debate (como demuestra este prrafo) sobre la
conveniencia o no captadores y definidores tienen que ser unidad de prueba, ya que
son tan "trivial". Les escribimos porque: a) no son triviales para escribir; b) que
tiene las pruebas paga dividendos en trminos de ahorro de tiempo para el tiempo
de cada cien puede ser atrapado por un captador chunga o colocador; yc) que
mejoran la cobertura de la prueba. Creamos un producto de cdigo auxiliar y
probamos cada getter y setter como un par en una sola prueba. Por lo general,
usted va a escribir uno o ms mtodos de prueba por mtodo de clase, con cada
mtodo de prueba probando una condicin particular en un mtodo de la clase,
como la comprobacin de un nulo valor de un argumento pasado al mtodo.
'Springapp / test / springapp / dominio / ProductTests.java' :
springapp.domain paquete;
junit.framework.TestCase importacin;
ProductTests clase pblica se extiende TestCase {
producto privado;
void Protected Setup () throws Exception {
producto = nuevo producto ();
}

pblica testSetAndGetDescription void () {


TestDescription String = "aDescription";
assertNull (product.getDescription ());
product.setDescription (testDescription);
assertEquals (testDescription, product.getDescription ());
}
pblica testSetAndGetPrice void () {
doble testPrice = 100,00;
assertEquals (0, 0, 0);
product.setPrice (testPrice);
assertEquals (testPrice, product.getPrice (), 0);
}
}
Siguiente creamos el ProductManager . Este es el servicio responsable de productos
de manipulacin. Contiene dos mtodos: un mtodo de negocio increasePrice
() que aumentan los precios de todos los productos y un mtodo getter getProducts
() para recuperar todos los productos. Hemos elegido para que sea una interfaz en
lugar de una clase concreta para un nmero de razones. En primer lugar, hace que
las pruebas unitarias de escritura para los controladores ms fcil (como veremos
en el siguiente captulo). En segundo lugar, el uso de interfaces significa JDK proxy
(una caracterstica del lenguaje Java) se puede utilizar para hacer que el
transaccional servicio en lugar de CGLIB (una biblioteca de generacin de cdigo).
'Springapp / src / java / springapp / servicio / ProductManager.java' :
springapp.service paquete;
java.io.Serializable importacin;
java.util.List importacin;
springapp.domain.Product importacin;
ProductManager interfaz pblica se extiende Serializable {
pblica increasePrice void (int porcentaje);
Lista pblica <productos> getProducts ();
}
Vamos

crear

el SimpleProductManager clase

que

implementa

la ProductManager interfaz.
'Springapp / src / java / springapp / servicio / SimpleProductManager.java' :
springapp.service paquete;
java.util.List importacin;
springapp.domain.Product importacin;
public class SimpleProductManager implementa ProductManager {

Lista pblico <Producto> getProducts () {


throw new UnsupportedOperationException ();
}
public void increasePrice (int porcentaje) {
throw new UnsupportedOperationException ();
}
setProducts public void (Lista <productos> productos) {
throw new UnsupportedOperationException ();
}
}
Antes de implementar los mtodos en SimpleProductManager , vamos a definir
algunas

pruebas

primero. La

definicin

ms

estricta

de Test

Driven

Development(TDD) es escribir siempre las pruebas primero, luego el cdigo. Una


interpretacin ms laxa de la misma es ms afn a la Prueba de Desarrollo
Orientado (TOD), donde alternamos entre el cdigo escrito y pruebas como parte
del proceso de desarrollo. Lo ms importante es para una base de cdigo para tener
tan completa un conjunto de pruebas de unidad como sea posible, as que cmo
lograr que se convierte en algo acadmico. La mayora de los desarrolladores de
TDD, sin embargo, no estn de acuerdo en que la calidad de las pruebas es siempre
mayor cuando se escriben en torno al mismo tiempo que el cdigo que se est
desarrollando, as que ese es el enfoque que vamos a tomar.
Para escribir pruebas eficaces, hay que considerar todas las posibles condiciones
pre y post de un mtodo se est probando, as como lo que sucede en el
mtodo.Vamos a empezar por probar una llamada a getProducts () devuelve nulo .
'Springapp / test / springapp / servicio / SimpleProductManagerTests.java' :
springapp.service paquete;
junit.framework.TestCase importacin;
public class SimpleProductManagerTests extiende TestCase {
privada ProductManager SimpleProductManager;
void Protected Setup () throws Exception {
ProductManager = new SimpleProductManager ();
}
testGetProductsWithNoProducts public void () {
ProductManager = new SimpleProductManager ();
assertNull (productManager.getProducts ());
}
}
Vuelva a ejecutar todas las pruebas JUnit y la prueba debe fallar como getProducts
() an no se ha implementado. Por lo general es una buena idea para marcar

mtodos

no

implementados

por

conseguir

que

lanzar

una UnsupportedOperationException .
Siguiente implementamos una prueba para recuperar una lista de productos de
cdigo auxiliar pobladas con datos de prueba. Sabemos que tendremos que rellenar
la

lista

de

productos

en

la

mayora

de

nuestros

mtodos

de

ensayo

en SimpleProductManagerTests , por lo que definimos la lista trozo de JUnit


enConfiguracin () , un mtodo que se invoca antes de llamar a cada mtodo de
ensayo.
'Springapp / test / springapp / servicio / SimpleProductManagerTests.java' :
springapp.service paquete;
java.util.ArrayList importacin;
java.util.List importacin;
springapp.domain.Product importacin;
junit.framework.TestCase importacin;
public class SimpleProductManagerTests extiende TestCase {
privada ProductManager SimpleProductManager;
Lista privada <Producto> productos;
private int PRODUCT_COUNT esttica = 2;
esttica CHAIR_PRICE privado Doble = new Double (20,50);
CHAIR_DESCRIPTION static String privada = "Presidente";
TABLE_DESCRIPTION static String privada = "Tabla";
esttica TABLE_PRICE privado Doble = new Double (150,10);
void Protected Setup () throws Exception {
ProductManager = new SimpleProductManager ();
productos = new ArrayList <Producto> ();
// Stub una lista de productos
Producto = nuevo producto ();
product.setDescription ("Presidente");
product.setPrice (CHAIR_PRICE);
products.add (producto);
producto = nuevo producto ();
product.setDescription ("Tabla");
product.setPrice (TABLE_PRICE);
products.add (producto);
productManager.setProducts (productos);
}
testGetProductsWithNoProducts public void () {
ProductManager = new SimpleProductManager ();
assertNull (productManager.getProducts ());
}
testGetProducts public void () {

Lista de productos> <= productos productManager.getProducts ();


assertNotNull (productos);
assertEquals (PRODUCT_COUNT, productManager.getProducts () size
().);
Producto = products.get (0);
assertEquals (CHAIR_DESCRIPTION, product.getDescription ());
assertEquals (CHAIR_PRICE, product.getPrice ());
producto = products.get (1);
assertEquals (TABLE_DESCRIPTION, product.getDescription ());
assertEquals (TABLE_PRICE, product.getPrice ());
}
}
Vuelva a ejecutar todas las pruebas JUnit y nuestros dos pruebas deben fallar.
Volvemos a la SimpleProductManager e implementamos los mtodos get y set para
el productos propiedad.
'Springapp / src / java / springapp / servicio / SimpleProductManager.java' :
springapp.service paquete;
java.util.ArrayList importacin;
java.util.List importacin;
springapp.domain.Product importacin;
public class SimpleProductManager implementa ProductManager {
Lista privada <Producto> productos;
Lista pblico <Producto> getProducts () {
devolver los productos;
}
public void increasePrice (int porcentaje) {
// Mtodo generado por el Auto TODO taln
}
setProducts public void (Lista <productos> productos) {
productos this.products =;
}
}
Vuelva a ejecutar las pruebas JUnit y todas nuestras pruebas deben pasar.
Se procede mediante la aplicacin de las siguientes pruebas para la increasePrice
() mtodo:

La lista de productos es nulo y el mtodo se ejecuta con gracia.

La lista de productos est vaca y el mtodo se ejecuta con gracia.

Establecer un aumento de precios del 10% y comprobar el aumento se

refleja en los precios de todos los productos de la lista.


'Springapp / test / springapp / servicio / SimpleProductManagerTests.java' :
springapp.service paquete;
java.util.ArrayList importacin;
java.util.List importacin;
springapp.domain.Product importacin;
junit.framework.TestCase importacin;
public class SimpleProductManagerTests extiende TestCase {
privada ProductManager SimpleProductManager;
Lista privada <Producto> productos;
private int PRODUCT_COUNT esttica = 2;
esttica CHAIR_PRICE privado Doble = new Double (20,50);
CHAIR_DESCRIPTION static String privada = "Presidente";
TABLE_DESCRIPTION static String privada = "Tabla";
esttica TABLE_PRICE privado Doble = new Double (150,10);
private int POSITIVE_PRICE_INCREASE esttica = 10;
void Protected Setup () throws Exception {
ProductManager = new SimpleProductManager ();
productos = new ArrayList <Producto> ();
// Stub una lista de productos
Producto = nuevo producto ();
product.setDescription ("Presidente");
product.setPrice (CHAIR_PRICE);
products.add (producto);
producto = nuevo producto ();
product.setDescription ("Tabla");
product.setPrice (TABLE_PRICE);
products.add (producto);
productManager.setProducts (productos);
}
testGetProductsWithNoProducts public void () {
ProductManager = new SimpleProductManager ();
assertNull (productManager.getProducts ());
}
testGetProducts public void () {
Lista de productos> <= productos productManager.getProducts ();
assertNotNull (productos);
assertEquals (PRODUCT_COUNT, productManager.getProducts () size ().);
Producto = products.get (0);

assertEquals (CHAIR_DESCRIPTION, product.getDescription ());


assertEquals (CHAIR_PRICE, product.getPrice ());
producto = products.get (1);
assertEquals (TABLE_DESCRIPTION, product.getDescription ());
assertEquals (TABLE_PRICE, product.getPrice ());
}
testIncreasePriceWithNullListOfProducts public void () {
try {
ProductManager = new SimpleProductManager ();
productManager.increasePrice (POSITIVE_PRICE_INCREASE);
}
capturas (NullPointerException ex) {
fallar ("Productos lista es nula.");
}
}
testIncreasePriceWithEmptyListOfProducts public void () {
try {
ProductManager = new SimpleProductManager ();
productManager.setProducts (new ArrayList <Producto> ());
productManager.increasePrice (POSITIVE_PRICE_INCREASE);
}
catch (Exception ex) {
fallar ("Productos lista est vaca.");
}
}
pblica testIncreasePriceWithPositivePercentage void () {
productManager.increasePrice (POSITIVE_PRICE_INCREASE);
doble expectedChairPriceWithIncrease = 22,55;
doble expectedTablePriceWithIncrease = 165,11;
Lista de productos> <= productos productManager.getProducts ();
Producto = products.get (0);
assertEquals

(expectedChairPriceWithIncrease,

product.getPrice

());
producto = products.get (1);
assertEquals

(expectedTablePriceWithIncrease,

product.getPrice

());
}
}
Volvemos a SimpleProductManager implementar increasePrice () .
'Springapp / src / java / springapp / servicio / SimpleProductManager.java' :

springapp.service paquete;
java.util.List importacin;
springapp.domain.Product importacin;
public class SimpleProductManager implementa ProductManager {
Lista privada <Producto> productos;
Lista pblico <Producto> getProducts () {
devolver los productos;
}
public void increasePrice (int porcentaje) {
si (productos! = null) {
para (producto: productos) {
doble nuevoPrecio = product.getPrice (). doubleValue () *
(100 + porcentaje) / 100;
product.setPrice (nuevoPrecio);
}
}
}
setProducts public void (Lista <productos> productos) {
productos this.products =;
}
}
Vuelva a ejecutar las pruebas JUnit y todas nuestras pruebas deben pasar. *
HURRAH * JUnit tiene un dicho: " . mantener la barra verde para mantener el
cdigo limpio "Para aquellos de ustedes ejecutar las pruebas en un IDE y son
nuevos en la unidad de pruebas, esperamos que te sientes imbuido de un sentido
de mayor sentido de confianza y certeza de que el cdigo est realmente
funcionando como se especifica en la especificacin de las reglas de negocio y como
usted piensa.Sin duda, nos hacemos.
Ahora estamos listos para volver a la capa web para poner una lista de productos
en nuestra Controller modelo.

3.3. Resumen
Echemos vistazo rpido a lo que hicimos en la parte 3.

Se implement un objeto de dominio del producto y una interfaz de

servicio ProductManager y clase concreta SimpleProductManager todos como


POJOs.

Escribimos pruebas unitarias para todas las clases que implementamos.

Nosotros

no

escribimos

una

lnea

de

cdigo

que

ver

con

la

primavera. Este es un ejemplo de cmo no invasiva es realmente el Spring


Framework. Uno

de

sus

objetivos

principales

es

permitir

los

desarrolladores centrarse en abordar la tarea ms importante de todos: para


ofrecer un valor por los requerimientos del negocio de modelado y
ejecucin. Otro de sus objetivos es hacer siguiendo las mejores prcticas
sencillas, como los servicios de aplicacin utilizando interfaces y pruebas
unitarias tanto como restricciones del proyecto es dadas pragmticas. A lo
largo de este tutorial, vers los beneficios de disear interfaces cobran vida.
Ponemos a tu disposicin una captura de pantalla de lo que su estructura de
directorios del proyecto debe ser similar despus de seguir las instrucciones
anteriores.

La estructura de directorios del proyecto al final de la parte 3

Captulo 4. Desarrollo de la Interfaz Web


Esta es la parte 4 de una cuenta paso a paso de cmo desarrollar una aplicacin
web desde cero usando Spring Framework. En la Parte 1 hemos configurado el
entorno y establecer una aplicacin bsica. En la Parte 2 refinamos la aplicacin que
vamos a construir. Parte 3 aade toda la lgica y la unidad de pruebas de
negocio. Ahora es el momento de construir la interfaz web real de la aplicacin.

4.1. Aadir referencia a la lgica de negocio en


el controlador
En primer lugar, vamos a cambiar el nombre de nuestra HelloController a algo ms
significativo. Qu tal InventoryController ya estamos construyendo un sistema de
inventario. Aqu

es

donde

un

IDE

con

refactorizacin

apoyo

es

invaluable. Renombramos HelloController a InventoryController y


los HelloControllerTests aInventoryControllerTests . A
el InventoryController para

mantener

continuacin,

una

Modificamos

referencia

la ProductManager clase. Tambin agregar cdigo para que el controlador de pasar


informacin de algunos productos a la vista. El getModelAndView () mtodo
devuelve ahora un mapa tanto con la fecha y la hora y la lista de los productos
obtenidos a partir de la referencia gerente.
'Springapp / src / java / springapp / web / InventoryController.java' :
springapp.web paquete;
org.springframework.web.servlet.mvc.Controller importacin;
org.springframework.web.servlet.ModelAndView de importacin;
javax.servlet.ServletException importacin;
javax.servlet.http.HttpServletRequest importacin;
javax.servlet.http.HttpServletResponse importacin;
java.io.IOException importacin;
java.util.Map importacin;
java.util.HashMap importacin;
org.apache.commons.logging.Log importacin;
org.apache.commons.logging.LogFactory importacin;
springapp.service.ProductManager importacin;
public class InventoryController implementa Controller {
registrador Iniciar ltima protegida = LogFactory.getLog (getClass ());
privada ProductManager ProductManager;
pblica

ModelAndView

handleRequest

(HttpServletRequest

request,

HttpServletResponse respuesta)
lanza ServletException, IOException {
Cadena ahora = (new java.util.Date ()) toString ().;
logger.info ("volver la vista hola con" + ahora);
Map <String, Object> myModel = new HashMap <String, Object> ();
myModel.put ("ahora", ahora);
myModel.put ("productos", this.productManager.getProducts ());
volver nueva ModelAndView ("modelo" "hola", myModel);
}
public void setProductManager (ProductManager ProductManager) {
this.productManager = ProductManager;

}
}
Tambin vamos a tener que modificar los InventoryControllerTests para suministrar
un ProductManager y extraer el valor de "ahora" del modelo de mapa antes de las
pruebas pasarn de nuevo.
'Springapp / test / web / InventoryControllerTests.java' :
springapp.web paquete;
java.util.Map importacin;
org.springframework.web.servlet.ModelAndView de importacin;
springapp.service.SimpleProductManager importacin;
springapp.web.InventoryController importacin;
junit.framework.TestCase importacin;
Clase pblica InventoryControllerTests extiende TestCase {
public void testHandleRequestView () throws Exception {
InventoryController controlador = new InventoryController ();
controller.setProductManager (nueva SimpleProductManager ());
ModelAndView ModelAndView = controller.handleRequest (null, null);
assertEquals ("hola", modelAndView.getViewName ());
assertNotNull (modelAndView.getModel ());
Mapa modelMap = (Mapa) modelAndView.getModel () conseguir
("modelo.");
Cadena nowValue = (String) modelMap.get ("ahora");
assertNotNull (nowValue);
}
}

4.2. Modificar la vista para mostrar los datos


de negocio y aadir soporte para mensaje
paquete
Utilizando la JSTL <c: forEach /> etiqueta, aadimos una seccin que muestra
informacin del producto. Tambin hemos reemplazado el ttulo, encabezado y el
saludo de texto con un JSTL <fmt: message /> etiqueta que extrae el texto a
mostrar de una proporcionada "mensaje" fuente - vamos a mostrar esta fuente en
un paso posterior.
'Springapp / build / web / WEB-INF / jsp / hello.jsp' :

<% @ Include file = "/ WEB-INF / jsp / include.jsp"%>


<Html>
<Head> <title> <fmt: message key = "ttulo" /> </ title> </ head>
<Body>
<H1> <fmt: message key = "la partida" /> </ h1>
<P> <fmt: message key = "saludo" /> <c: Fuera value = "$
{model.now}" /> </ p>
<H3> Productos </ h3>
<C: artculos foreach = "$ {} model.products" var = "prod">
<c: Fuera value = "$ {prod.description}" /> <i> $ <c: Fuera value =
"$ {prod.price}" /> </ i> <br>
</ C: forEach>
</ Body>
</ Html>

4.3. Aadir algunos datos de prueba para


rellenar automticamente algunos objetos de
negocio
Es

el

momento

de

aadir

un SimpleProductManager a

nuestro

archivo

de

configuracin y aconteci que en el organismo de la InventoryController . No vamos


a aadir cualquier cdigo para cargar los objetos de negocio a partir de una base de
datos por el momento. En cambio, podemos stub un par de Producto casos usando
frijoles y aplicacin de soporte contexto de la Primavera. Simplemente vamos a
poner los datos que necesitamos como un par de entradas de frijol en'springappservlet.xml' . Tambin vamos a aadir el 'MessageSource' entrada de frijol que se
tire en el paquete de mensajes de recursos ( 'messages.properties' ) que crearemos
en el siguiente paso. Asimismo, recuerda a cambiar el nombre de la referencia
a HelloController a InventoryController desde que cambiamos el nombre de ella.
'Springapp / build / web / WEB-INF / springapp-servlet.xml' :
<? Xml version = "1.0" encoding = "UTF-8"?>
<frijoles 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 ">
<! - La definicin de contexto de aplicacin para la springapp
DispatcherServlet ->
<Bean

id

clase

"springapp.service.SimpleProductManager">

"ProductManager"

<Property name = "productos">


<Lista>
<Ref frijol = "producto1" />
<Ref frijol = "product2" />
<Ref frijol = "Product3" />
</ List>
</ Property>
</ Bean>
<Bean id = clase "producto1" = "springapp.domain.Product">
<Property name = "description" value = "lmpara" />
<Property name = "precio" value = "5.75" />
</ Bean>
<Bean id = clase "product2" = "springapp.domain.Product">
<Property name = "description" value = "Tabla" />
<Property name = "precio" value = "75,25" />
</ Bean>
<Bean id = clase "Product3" = "springapp.domain.Product">
<Property name = "description" value = "Presidente" />
<Property name = "precio" value = "22,79" />
</ Bean>
<Bean

id

clase

"MessageSource"

"org.springframework.context.support.ResourceBundleMessageSource">
<Property name = "nombre base" value = "mensajes" />
</ Bean>
<Nombre

del

bean

"/

hello.htm"

class

"springapp.web.

InventoryController ">
<Property name = "ProductManager" ref = "ProductManager" />
</ Bean>
<Bean

id

clase

"ViewResolver"

"org.springframework.web.servlet.view.InternalResourceViewResolver">
<Propiedad

nombre

valor

"viewClass"

"org.springframework.web.servlet.view.JstlView" />
<Propiedad nombre = valor "prefijo" = "/ WEB-INF / jsp /" />
<Property name = "sufijo" value = ". Jsp" />
</ Bean>
</ Beans>

4.4. Agregue el grupo de mensajes


Creamos

un 'messages.properties' archivo

en

el '/

classes

web

WEB-

INF' directorio. Estas propiedades agrupar hasta ahora tiene tres entradas que

coincidan las claves especificadas en los <fmt: Mensaje /> etiquetas que hemos
aadido a 'hello.jsp' .
'springapp / build / web / WEB-INF / classes / messages.properties' :
title = SpringApp
rbrica = Hola :: SpringApp
felicitacin = Saludos, es ahora
Ahora volver a generar la aplicacin y desplegarla. Vamos a tratar de acceder a esta
nueva versin de la aplicacin y usted debera ver lo siguiente:

La aplicacin actualizada

4.5. Adicin de un formulario


Para proporcionar una interfaz en la aplicacin web para exponer la funcionalidad
de aumento de precios, aadimos una forma que permita que el usuario introduzca
un valor de porcentaje. Este formulario utiliza una biblioteca de etiquetas
llamado "primavera-form.tld

' que

se

proporciona

con

el

Spring

Framework.Tenemos que copiar este archivo de la distribucin de la primavera


( "spring-marco-2.5 / dist / resources / primavera-form.tld ' ) a la 'springapp /
web / WEB-INF / tld' directorio que tambin tenemos que crear. Siguiente tambin
hay que aadir un <taglib /> entrada a la 'web.xml' archivo.

'Springapp / build / web / WEB-INF / web.xml' :


<? Xml version = "1.0" encoding = "UTF-8"?>
<Versin web-app = "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 ">
<Servlet>
<Servlet-name> springapp </ servlet-name>
<Servlet-class> org.springframework.web.servlet.DispatcherServlet </ servletclass>
<Load-on-startup> 1 </ load-on-startup>
</ Servlet>
<Servlet-mapping>
<Servlet-name> springapp </ servlet-name>
<Url-pattern> *. Htm </ url-pattern>
</ Servlet-mapping>
<Welcome-file-list>
<Welcome-file>
index.jsp
</ Welcome-file>
</ Welcome-file-list>
<Jsp-config>
<Taglib>
<Taglib-uri> / primavera </ uri-taglib>
<Taglib-location> /WEB-INF/tld/spring-form.tld </ taglib-location>
</ Taglib>
</ Jsp-config>
</ Web-app>
Tambin tenemos que declarar este taglib en una directiva de pgina en el archivo
jsp y, a continuacin, empezar a utilizar las etiquetas por lo tanto hemos
importado. Aadir la pgina JSP 'priceincrease.jsp' a la 'build / web / WEB-INF /
jsp' directorio.
'Springapp / build / web / WEB-INF / jsp / priceincrease.jsp' :
<% @ Include file = "/ WEB-INF / jsp / include.jsp"%>
<%

Taglib

prefix

"http://www.springframework.org/tags/form"%>
<Html>
<Head>
<Title> <fmt: message key = "title" /> </ title>

"forma"

uri

<Style>
.Error {color: red; }
</ Style>
</ Head>
<Body>
<H1> <fmt: message key = "priceincrease.heading" /> </ h1>
<Form: form method = "post" CommandName = "priceIncrease">
<Table width = "95%" bgcolor = "f8f8ff" border = "0" cellspacing = "0"
cellpadding = "5">
<Tr>
<Td align = "right" width = "20%"> Aumento (%): </ td>
<Td width = "20%">
<Form: entrada path = "porcentaje" />
</ Td>
<Td width = "60%">
<Form: ruta errores = "porcentaje" CssClass = "error" />
</ Td>
</ Tr>
</ Table>
<br>
<Input type = "submit" align = "center" value = "Ejecutar">
</ Form: form>
<a href="<c:url value="hello.htm"/> "> Inicio </a>
</ Body>
</ Html>
Esta prxima clase es una clase JavaBean muy simple, y en nuestro caso hay una
sola propiedad con un getter y setter. Este es el objeto de que el formulario se
rellenar y que nuestra lgica de negocio que va a extraer el porcentaje de
incremento de los precios.
'Springapp / src / java / springapp / servicio / PriceIncrease.java' :
springapp.service paquete;
org.apache.commons.logging.Log importacin;
org.apache.commons.logging.LogFactory importacin;
public class PriceIncrease {
/ ** Logger para esta clase y subclases * /
registrador Iniciar ltima protegida = LogFactory.getLog (getClass ());
porcentaje int privado;
public void setPercentage (int i) {
porcentaje = i;
logger.info ("Porcentaje configurado en" + i);
}

public int getPercentage () {


volver porcentaje;
}
}
La siguiente clase de validador obtiene el control cuando el usuario presiona
someten. Los valores introducidos en la forma se establecern en el objeto de
comando por el marco. La validacin (..) se llama al mtodo y el objeto de
comando ( PriceIncrease ) y un objeto de contexto para sostener cualquier error se
pasan en.
'Springapp / src / java / springapp / servicio / PriceIncreaseValidator.java' :
springapp.service paquete;
org.springframework.validation.Validator importacin;
org.springframework.validation.Errors de importacin;
org.apache.commons.logging.Log importacin;
org.apache.commons.logging.LogFactory importacin;
public class PriceIncreaseValidator implementa Validador {
int DEFAULT_MIN_PERCENTAGE privada = 0;
int DEFAULT_MAX_PERCENTAGE privado = 50;
privada int minPercentage = DEFAULT_MIN_PERCENTAGE;
privada int maxPercentage = DEFAULT_MAX_PERCENTAGE;
/ ** Logger para esta clase y subclases * /
registrador Iniciar ltima protegida = LogFactory.getLog (getClass ());
soportes booleanos pblicos (clazz Clase) {
PriceIncrease.class.equals retorno (clazz);
}
public void validate (Object obj, los errores Errores) {
PriceIncrease pi = (PriceIncrease) obj;
si (pi == null) {
("especifica

error.not"

"porcentaje",

null,

"requiere

valor.")

errors.rejectValue;
}
else {
logger.info ("Validacin con" + pi + ":" + pi.getPercentage ());
si (pi.getPercentage ()> maxPercentage) {
errors.rejectValue ("porcentaje", "error.too-alta",
nueva Object [] {new Integer (maxPercentage)}, "Valor demasiado
alto.");
}
si (pi.getPercentage () <= minPercentage) {
errors.rejectValue ("porcentaje", "error.too-baja",

nueva Object [] {new Integer (minPercentage)}, "Valor demasiado


bajo.");
}
}
}
public void setMinPercentage (int i) {
minPercentage = i;
}
public int getMinPercentage () {
volver minPercentage;
}
public void setMaxPercentage (int i) {
maxPercentage = i;
}
public int getMaxPercentage () {
volver maxPercentage;
}
}

4.6. Adicin de un controlador de forma


Ahora tenemos que aadir una entrada en el 'springapp-servlet.xml' archivo para
definir la nueva forma y el controlador. Definimos objetos para inyectar en
propiedades para commandClass y validador . Tambin especificamos dos vistas,
una FormView que se utiliza para la forma y un successView que vamos a ir
despus de procesamiento de formularios xito. Este ltimo puede ser de dos
tipos. Puede ser una referencia vista normal que se reenva a una de nuestras
pginas JSP. Una desventaja de este enfoque es que si el usuario actualiza la
pgina, los datos del formulario se presenta de nuevo, y que acabara con un
aumento del doble precio. Una forma alternativa es utilizar una redireccin, donde
se enva de vuelta una respuesta al navegador del usuario instruir a redirigir a una
nueva URL. La URL que usamos en este caso no puede ser una de nuestras pginas
JSP, ya que se ocultan de acceso directo. Tiene que ser una direccin URL que es
externamente accesible. Hemos optado por utilizar 'hello.htm' como mi URL de
redireccionamiento. Esta URL se asigna al 'hello.jsp' la pgina, por lo que esto
debera funcionar bien.
'Springapp / build / web / WEB-INF / springapp-servlet.xml' :
<? Xml version = "1.0" encoding = "UTF-8"?>
<frijoles 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 ">
<!

La

definicin

de

contexto

de

aplicacin

para

la

springapp

DispatcherServlet ->
<beans>
<Bean id = clase "ProductManager" = "springapp.service.ProductManager">
<Property name = "productos">
<Lista>
<Ref frijol = "producto1" />
<Ref frijol = "product2" />
<Ref frijol = "Product3" />
</ List>
</ Property>
</ Bean>
<Bean id = clase "producto1" = "bus.Product">
<Property name = "description" value = "lmpara" />
<Property name = "precio" value = "5.75" />
</ Bean>
<Bean id = clase "product2" = "bus.Product">
<Property name = "description" value = "Tabla" />
<Property name = "precio" value = "75,25" />
</ Bean>
<Bean id = clase "Product3" = "bus.Product">
<Property name = "description" value = "Presidente" />
<Property name = "precio" value = "22,79" />
</ Bean>
<Bean

id

clase

"MessageSource"

"org.springframework.context.support.ResourceBundleMessageSource">
<Property name = "nombre base" value = "mensajes" />
</ Bean>
<Nombre del bean = clase "/ hello.htm" = "springapp.web.InventoryController">
<Property name = "ProductManager" ref = "ProductManager" />
</ Bean>
<Nombre

del

bean

clase

"/

priceincrease.htm"

"springapp.web.PriceIncreaseFormController">
<Property name = "sessionForm" value = "true" />
<Propiedad nombre = valor "CommandName" = "priceIncrease" />
<Propiedad

nombre

valor

"commandClass"

"springapp.service.PriceIncrease" />
<Property name = "validador">
<Bean class = "springapp.service.PriceIncreaseValidator" />
</ Property>

<Propiedad nombre = valor "FormView" = "priceincrease" />


<Property name = "successView" value = "hello.htm" />
<Property name = "ProductManager" ref = "ProductManager" />
</ Bean>
<Bean

id

clase

"ViewResolver"

"org.springframework.web.servlet.view.InternalResourceViewResolver">
<Propiedad

nombre

valor

"viewClass"

"org.springframework.web.servlet.view.JstlView" />
<Propiedad nombre = valor "prefijo" = "/ WEB-INF / jsp /" />
<Property name = "sufijo" value = ". Jsp" />
</ Bean>
</ Beans>
A

continuacin,

vamos

echar

un

vistazo

el

controlador

para

este

formulario. El onSubmit (..) mtodo obtiene el control y hace algo de registro antes
de

que

llama

continuacin,

al increasePrice

devuelve

(..) mtodo

un ModelAndView pasar

en
en

la ProductManager objeto. A
una

nueva

instancia

un RedirectViewcreado usando el URL para la vista del xito.


'Springapp / src / java / springapp / web / PriceIncreaseFormController.java' :
springapp.web paquete;
org.springframework.web.servlet.mvc.SimpleFormController importacin;
org.springframework.web.servlet.ModelAndView de importacin;
org.springframework.web.servlet.view.RedirectView de importacin;
javax.servlet.ServletException importacin;
javax.servlet.http.HttpServletRequest importacin;
org.apache.commons.logging.Log importacin;
org.apache.commons.logging.LogFactory importacin;
springapp.service.ProductManager importacin;
springapp.service.PriceIncrease de importacin;
public class PriceIncreaseFormController extiende SimpleFormController {
/ ** Logger para esta clase y subclases * /
registrador Iniciar ltima protegida = LogFactory.getLog (getClass ());
privada ProductManager ProductManager;
pblica ModelAndView onSubmit (comando Objeto)
lanza ServletException {
int incremento = ((PriceIncrease) de comandos) .getPercentage ();
logger.info ("El aumento de los precios en un" + + aumento "%.");
productManager.increasePrice (aumento);
logger.info ("volver a la vista PriceIncreaseForm a" + getSuccessView ());
volver nueva ModelAndView (nueva RedirectView (getSuccessView ()));
}

de

formBackingObject

objeto

protegido

(HttpServletRequest

request)

throws

ServletException {
PriceIncrease priceIncrease = new PriceIncrease ();
priceIncrease.setPercentage (20);
volver priceIncrease;
}
public void setProductManager (ProductManager ProductManager) {
this.productManager = ProductManager;
}
pblica ProductManager getProductManager () {
volver ProductManager;
}
}
Tambin estamos aadiendo algunos mensajes a la '' messages.properties archivo
de recursos.
'springapp / build / web / WEB-INF / classes / messages.properties' :
title = SpringApp
rbrica = Hola :: SpringApp
felicitacin = Saludos, es ahora
priceincrease.heading = Precio Aumentar :: SpringApp
error.not especificado-= Porcentaje no especificado !!!
error.too baja = Debe especificar un porcentaje superior a {0}!
-error.too Alta = don''t seas codicioso - que can''t subir los precios de ms
de {0}%!
required = Entrada necesario.
typeMismatch = datos no vlidos.
typeMismatch.percentage = Eso no es un nmero !!!
Compilar y desplegar todo esto y despus de volver a cargar la aplicacin podemos
probarlo. Esto es lo que la forma se parece con errores que aparezcan.
Por ltimo, vamos a aadir un enlace a la pgina de subida de precios
del 'hello.jsp' .
<% @ Include file = "/ WEB-INF / jsp / include.jsp"%>
<Html>
<Head> <title> <fmt: message key = "ttulo" /> </ title> </ head>
<Body>
<H1> <fmt: message key = "la partida" /> </ h1>
<P> <fmt: message key = "saludo" /> <c: Fuera value = "$ {model.now}" />
</ p>

<H3> Productos </ h3>


<C: artculos foreach = "$ {} model.products" var = "prod">
<c: Fuera value = "$ {prod.description}" /> <i> $ <c: Fuera value = "$
{prod.price}" /> </ i> <br>
</ C: forEach>
<br>
<a href="<c:url value="priceincrease.htm"/> "> Aumentar los precios
</a>
<br>
</ Body>
</ Html>
Ahora, volver a implementar y probar la nueva funcin de aumento de precios.

La aplicacin actualizada

4.7. Resumen
Echemos un vistazo a lo que hicimos en la parte 4.

le

Hemos cambiado el nombre a nuestro controlador InventoryController y


dimos

una

referencia

un ProductManager para

recuperar una lista de los productos para mostrar.

que

pudiramos

Siguiente modificamos la pgina JSP a utilizar un paquete de mensajes

para texto esttico y tambin aadimos un bucle foreach para mostrar la


lista dinmica de los productos.

A continuacin, definimos algunos datos de prueba para poblar los

objetos de negocio modificamos la pgina JSP a utilizar un paquete de


mensajes de texto esttico y tambin aadimos un bucle foreach para
mostrar la lista dinmica de los productos.

Siguiente modificamos la pgina JSP a utilizar un paquete de mensajes

para texto esttico y tambin aadimos un bucle foreach para mostrar la


lista dinmica de los productos.

Despus de esto funcion hemos creado una forma para proporcionar

la capacidad de aumentar los precios. Siguiente modificamos la pgina JSP a


utilizar un paquete de mensajes para texto esttico y tambin aadimos un
bucle foreach para mostrar la lista dinmica de los productos.

Finalmente creamos el controlador de forma y un validador y

desplegamos y probamos las nuevas caractersticas.


Ponemos a tu disposicin una captura de pantalla de lo que su estructura de
directorios del proyecto debe ser similar despus de seguir las instrucciones
anteriores.

La estructura de directorios del proyecto al final de la parte 4

Captulo 5. Implementacin de persistencia de


base de datos
Esta es la parte 5 de una cuenta paso a paso de cmo desarrollar una aplicacin
web desde cero usando Spring Framework. En la Parte 1 hemos configurado el
entorno y establecer una aplicacin bsica. En la Parte 2 refinamos la aplicacin que
vamos a construir. Parte 3 aade toda la lgica y la unidad de pruebas de negocio
y la parte 4 desarroll la interfaz web. Ahora es el momento de introducir la
persistencia de base de datos. Vimos en las partes anteriores de cmo cargamos
algunos objetos de negocio utilizando las definiciones de frijol en un archivo de
configuracin. Es obvio que esto nunca iba a funcionar en la vida real - cada vez
que re-iniciar el servidor estamos de vuelta a los precios originales. Tenemos que
aadir cdigo para persistir en realidad estos cambios en una base de datos.

5.1. Crear base de datos de secuencia de


comandos de inicio
Antes

de

que

podamos

empezar

desarrollar

el cdigo

de

persistencia,

necesitamos una base de datos. Estamos planeando sobre el uso de HSQL, que es
una buena base de datos de cdigo abierto escrito en Java. Esta base de datos se
distribuye con la primavera, por lo que ya forma parte del directorio lib de la
aplicacin web. Usaremos HSQL en modo servidor independiente. Eso significa que
vamos a tener que poner en marcha un servidor de base de datos independiente en
lugar de confiar en una base de datos integrada, pero nos da un acceso ms fcil
para ver los cambios realizados en la base de datos cuando se ejecuta la aplicacin
web.
Necesitamos un archivo script o por lotes para iniciar la base de datos. Crear
un 'db' directorio

en

el

principal 'springapp' directorio. Este

nuevo

directorio

contendr los archivos de base de datos. Ahora, vamos y agregar un script de


inicio:
Para Linux / Mac OS X aadir:
'Springapp / db / server.sh' :
java -classpath ../build/web/WEB-INF/lib/hsqldb.jar org.hsqldb.Server -database
prueba
No se olvide de cambiar el permiso de ejecucin al ejecutar 'chmod + x
server.sh' .

Para Windows aadir:


'Springapp / db / server.bat' :
-classpath java .. \ build \ web \ WEB-INF \ lib \ hsqldb.jar org.hsqldb.Server
-database prueba
Ahora se

puede

abrir una

ventana de

comandos, cambie al 'springapp /

db' directorio y empezar a la base de datos mediante la ejecucin de una de estas


secuencias de comandos de inicio.

5.2. Crear tablas y secuencias de comandos de


prueba de datos
En primer lugar, vamos a revisar la sentencia SQL necesaria para crear la
tabla. Creamos el archivo 'create_products.sql' en el directorio db.
'Springapp / db / create_products.sql' :
CREATE TABLE productos (
Identificacin del INTEGER NOT NULL PRIMARY KEY,
Descripcin varchar (255),
decimal precio (15,2)
);
CREAR products_description NDICE DE LA productos (descripcin);
Ahora tenemos que aadir nuestros datos de prueba. Cree el archivo 'load_data.sql'
en el directorio db.
'Springapp / db / load_data.sql' :
INSERT INTO productos (Identificacin, descripcin, precio) valores (1, 'lmpara',
5,78);
INSERT INTO productos (Identificacin, descripcin, precio) valores (2, 'Tabla',
75,29);
INSERT INTO productos (Identificacin, descripcin, precio) valores (3, 'Presidente',
22,81);
En la siguiente seccin vamos a ver cmo podemos ejecutar estos scripts SQL
desde el IDE.

5.3. Ejecutar secuencias de comandos y datos


de ensayos de carga
Vamos a crear tablas y rellenar con los datos de prueba utilizando las capacidades
de SQL incorporadas de IDE. Para utilizar esta tenemos que aadir la conexin de
base de datos a la base de datos HSQL.

Configuracin de una conexin de base de datos


Siguiente ejecutamos la creacin de tablas y secuencias de comandos de prueba de
carga de datos utilizando la opcin Ejecutar SQL desde el IDE.

La ejecucin de los scripts de SQL


Seleccione los datos de la tabla usando la ventana de comandos SQL.

Ejecutar la consulta de seleccin desde la ventana de comandos SQL

Ahora se puede ejecutar createTable y loadData para preparar los datos de prueba
que utilizaremos ms adelante.

5.4. Crear un objeto de acceso a datos (DAO)


aplicacin para JDBC
Comience

con

la

creacin

de

un

nuevo 'springapp

src

springapp

repositorio directorio para contener clases que se utilizan para el acceso de base de
datos. En este directorio se crea una nueva interfaz llamada ProductDAO . Esta ser
la interfaz que define la funcionalidad que las clases de implementacin DAO
proporcionar - podramos optar por tener ms de una aplicacin algn da.
'Springapp / src / java / springapp / repositorio / ProductDao.java' :
springapp.repository paquete;
java.util.List importacin;
springapp.domain.Product importacin;
interfaz pblica ProductDAO {
Lista pblico <Producto> getProductList ();
pblica saveProduct void (prod Producto);
}
Seguiremos esto con una clase llamada JdbcProductDao que ser la aplicacin JDBC
de esta interfaz. Spring proporciona una abstraccin JDBC marco que vamos a
hacer uso de. La mayor diferencia entre el uso de JDBC recta y marco JDBC de
primavera es que usted no tiene que preocuparse acerca de cmo abrir y cerrar la
conexin o cualquier declaracin. Todo se maneja para usted. Otra ventaja es que
usted no tendr que tomar ninguna excepcin, a menos que quieras. Primavera
envuelve todos SQLExceptions en su propia jerarqua de excepciones sin control
heredando de DataAccessException. Si quieres, puedes atrapar esta excepcin,
pero como la mayora de las excepciones de bases de datos son imposibles de
recuperar de todos modos, puede ser que tambin acaba de dejar que la excepcin
se propaga hasta un nivel ms alto. La clase SimpleJdbcDaoSupport ofrece un
cmodo acceso a una ya configurado SimpleJdbcTemplate , as que extender esta
clase. Todos

tendremos

que

dar

en

el

contexto

de

la

aplicacin

configurado DataSource .
'Springapp / src / java / springapp / repositorio / JdbcProductDao.java' :
springapp.repository paquete;
java.sql.ResultSet importacin;
java.sql.SQLException importacin;

es

una

java.util.List importacin;
org.apache.commons.logging.Log importacin;
org.apache.commons.logging.LogFactory importacin;
org.springframework.jdbc.core.namedparam.MapSqlParameterSource importacin;
org.springframework.jdbc.core.simple.ParameterizedRowMapper importacin;
org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport importacin;
springapp.domain.Product importacin;
public

class

JdbcProductDao

extiende

SimpleJdbcDaoSupport

implementa

ProductDAO {
/ ** Logger para esta clase y subclases * /
registrador Iniciar ltima protegida = LogFactory.getLog (getClass ());
Lista pblico <Producto> getProductList () {
logger.info ("productos Cmo!");
Lista de productos> <= productos getSimpleJdbcTemplate (). Consulta (
"Seleccione Identificacin, descripcin, precio de los productos",
nueva ProductMapper ());
devolver los productos;
}
public void saveProduct (prod Producto) {
logger.info ("producto de ahorro:" + prod.getDescription ());
int cuenta = getSimpleJdbcTemplate (). update (
"Los productos de actualizacin Descripcin set =: descripcin, precio =
Precio de donde id =: id",
nueva

MapSqlParameterSource

().

AddValue

("descripcin",

prod.getDescription ())
.addValue ("precio", prod.getPrice ())
.addValue ("id", prod.getId ()));
logger.info ("Filas afectadas:" + count);
}
privada ProductMapper clase esttica implementa ParameterizedRowMapper
<Producto> {
Producto pblica mapRow (ResultSet rs, int rownum) throws SQLException {
Producto prod = nuevo producto ();
prod.setId (rs.getInt ("id"));
prod.setDescription (rs.getString ("descripcin"));
prod.setPrice (nuevo doble (rs.getDouble ("precio")));
volver prod;
}
}
}

Vamos

repasar

los

dos

mtodos

ampliando SimpleJdbcSupport obtenemos

DAO

en

esta

clase. Desde

estamos

una SimpleJdbcTemplate preparado

listo para usar. Se accede llamando al getSimpleJdbcTemplate () mtodo.


El

primer

mtodo, getProductList

() ejecuta

una

consulta

utilizando

el SimpleJdbcTemplate . Simplemente ofrecemos la sentencia SQL y una clase que


puede manejar la correspondencia entre el conjunto de resultados y el producto de
clase. En nuestro caso el asignador de fila es una clase llamada ProductMapper que
definimos como una clase interna de la DAO. Esta clase hasta ahora no se utiliza
fuera de la DAO as por lo que es una clase interna funciona bien.
El ProductMapper implementa el ParameterizedRowMapper interfaz que define un
nico mtodo denominado mapRow que debe implementarse. Este mtodo mapear
los datos de cada fila en una clase que representa la entidad est recuperando en
su consulta. Desde el RowMapper es parametrizada, el mapRow mtodo devuelve el
tipo real que se crea.
El

segundo

mtodo

saveProduct

tambin

est

utilizando

el SimplJdbcTemplate . Esta vez nos estn llamando la actualizacin mtodo de


pasar en una sentencia SQL junto con los valores de los parmetros en la forma de
un MapSqlParameterSource . El uso de un MapSqlParameterSource nos permite
utilizar parmetros con nombre en lugar de la tpica "?" colocar los titulares que
usted est acostumbrado desde escribir JDBC simple. Los parmetros con nombre
hace que el cdigo sea ms explcita y evitar los problemas causados por los
parmetros que se establecen fuera de servicio, etc. El mtodo de actualizacin
devuelve el nmero de filas afectadas.
Tenemos que almacenar el valor de la clave principal para cada producto en la clase
de producto. Esta clave se utilizar cuando persistimos cualquier cambio al objeto
de nuevo a la base de datos. Para mantener esta clave aadimos un campo privado
llamado "id" completar con setters y getters a Product.java.
'Springapp / src / java / springapp / dominio / Product.java' :
springapp.domain paquete;
java.io.Serializable importacin;
clase Product pblica implementa Serializable {
Identificacin del int privado;
Descripcin private String;
Precio Doble privado;
public void setId (int i) {
id = i;
}
public int getId () {

volver Identificacin;
}
public String getDescription () {
Descripcin de vuelta;
}
public void setDescription (descripcin String) {
this.description = descripcin;
}
Doble getPrice pblica () {
Precio regresar;
}
pblica setPrice void (Precio Doble) {
this.price = precio;
}
public String toString () {
Tampn StringBuffer = new StringBuffer ();
buffer.append ("Descripcin:" + Descripcin + ";");
buffer.append ("Precio:" + precio);
volver buffer.toString ();
}
}
Esto completa la aplicacin JDBC simple de nuestra capa de persistencia.

5.5. Implementar pruebas para la aplicacin


JDBC DAO
Tiempo para aadir pruebas para la implementacin DAO JDBC. Spring proporciona
un marco de pruebas extensa que apoya JUnit 3.8 y 4, as como TestNG.Nosotros
no

podemos

cubrir

todo

eso

en

esta

gua,

pero

vamos

a mostrar

una

implementacin sencilla de la ayuda especfica JUnit 3.8. Tenemos que aadir el


archivo jar que contiene el marco de pruebas de primavera en nuestro
proyecto. Aadir primavera-test.jar de la 'primavera-marco-2.5 / dist / modules' en
el directorio 'Bibliotecas'.
Ahora

podemos

crear

nuestra

clase

de

extienden AbstractTransactionalDataSourceSpringContextTests tenemos

prueba. Por
una

gran

cantidad de buenas caractersticas de forma gratuita. Obtenemos la inyeccin de


dependencia de cualquier organismo pblico de un contexto de aplicacin. Este
contexto de aplicacin se carga por el marco de ensayo. Todo lo que necesitamos
hacer es especificar el nombre para l en el getConfigLocations mtodo. Tambin

recibimos la oportunidad de preparar nuestra base de datos con los datos de las
pruebas correspondientes en el onSetUpInTransaction mtodo. Esto es importante,
ya que no sabemos el estado de la base de datos cuando ejecutamos nuestras
pruebas. Mientras exista la tabla vamos a aclararlo y cargar lo que necesitamos
para nuestras pruebas. Desde estamos extendiendo una prueba "transaccional",
cualquier cambio que hagamos sern rodados automticamente una vez que
finalice la prueba.Los deleteFromTables y executeSqlScript mtodos se define en la
superclase, as que no tienen que ponerlas en prctica para cada prueba. Slo tiene
que pasar en los nombres de tabla que desea borrar y el nombre de la secuencia de
comandos que contiene los datos de prueba.
'Springapp / test / springapp / dominio / JdbcProductDaoTests.java' :
springapp.repository paquete;
java.util.List importacin;
org.springframework.test.AbstractTransactionalDataSourceSpringContextTests

de

importacin;
springapp.domain.Product importacin;
JdbcProductDaoTests

clase

pblica

se

extiende

AbstractTransactionalDataSourceSpringContextTests {
privada ProductDAO ProductDAO;
public void setProductDao (ProductDAO ProductDAO) {
this.productDao = ProductDAO;
}
@ Override
String [] getConfigLocations protegidas () {
volver new String [] {"ruta de clase: test-context.xml"};
}
@ Override
void protegida onSetUpInTransaction () throws Exception {
super.deleteFromTables (new String [] {"productos"});
super.executeSqlScript ("file: db / load_data.sql", true);
}
pblica testGetProductList void () {
Lista <productos> productos productDao.getProductList = ();
assertEquals ("nmero incorrecto de productos?", 3, products.size ());
}
pblica testSaveProduct void () {
Lista <productos> productos productDao.getProductList = ();
para (p producto: productos) {
p.setPrice (200.12);
productDao.saveProduct (p);
}
Lista <Producto> updatedProducts = productDao.getProductList ();

para (p Producto: updatedProducts) {


assertEquals ("precio equivocado de producto?", 200.12, p.getPrice ());
}
}
}
No tenemos el archivo de contexto de aplicacin que se carga para esta prueba, sin
embargo, as que vamos a crear este archivo en el 'springapp / test' directorio:
'Springapp / test / prueba context.xml' :
<? Xml version = "1.0" encoding = "UTF-8"?>
<frijoles 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 ">
<! - La definicin de contexto de aplicacin de prueba para las pruebas basadas
jdbc ->
<Bean id = clase "ProductDAO" = "springapp.repository.JdbcProductDao">
<Property name = "dataSource" ref = "dataSource" />
</ Bean>
<Bean

id

"dataSource"

class

"org.springframework.jdbc.datasource.DriverManagerDataSource">
<Propiedad

nombre

valor

"driverClassName"

"$

{jdbc.driverClassName}" />
<Propiedad nombre = valor "url" = "$ {jdbc.url}" />
<Property name = "nombre de usuario"

value = "$ {jdbc.username}" />

<Propiedad nombre = valor "password" = "$ {jdbc.password}" />


</ Bean>
<Bean id = "propertyConfigurer"
class

"org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<Property name = "ubicaciones">
<Lista>
<Valor> classpath: jdbc.properties </ value>
</ List>
</ Property>
</ Bean>
<Bean id = "transactionManager"
class
"org.springframework.jdbc.datasource.DataSourceTransactionManager">
<Property name = "dataSource" ref = "dataSource" />
</ Bean>
</ Beans>

Hemos definido un ProductDAO que es la clase que estamos probando. Tambin


hemos definido un DataSource con marcadores de posicin para los valores de
configuracin. Estos valores se proporcionan a travs de un archivo de separacin
de bienes y en tiempo de ejecucin, el PropertyPlaceholderConfigurer que hemos
definido leer este fichero propiedad y sustituir los marcadores de posicin con los
valores reales. Esto es conveniente ya que asla los valores de conexin en su
propio archivo. Estos valores a menudo necesitan ser cambiado durante el
despliegue de la aplicacin. Ponemos este nuevo archivo en la 'web / WEB-INF /
classes' directorio por lo que estar disponible cuando ejecutamos la aplicacin y
tambin despus, cuando desplegamos la aplicacin web. El contenido de este
archivo de propiedades es:
'springapp / build / web / WEB-INF / classes / jdbc.properties' :
jdbc.driverClassName = org.hsqldb.jdbcDriver
jdbc.url = jdbc: hsqldb: hsql: // localhost
jdbc.username = sa
jdbc.password =
Desde hemos aadido un archivo de configuracin a la 'prueba' "directorio y un
archivo jdbc.properties a la 'WEB-INF / classes' directorio, vamos a aadir una
nueva entrada de ruta de clases para nuestras pruebas. Es shoud ir despus de la
definicin de la "prueba .dir ' propiedad:
'Springapp / build.xml' :
...
<Property name = "test.dir" value = "test" />
<Identificacin del path = "prueba de ruta de clases">
<Conjunto de archivos dir = "$ {} web.dir / WEB-INF / lib">
<Include name = "*. Jar" />
</ Conjunto de archivos>
<Path pathelement = "$ {build.dir}" />
<Path pathelement = "$ {test.dir}" />
<Path pathelement = "$ {} web.dir / WEB-INF / classes" />
</ Path>
...
Ahora deberamos tener suficiente para nuestras pruebas para correr y pasar, pero
es una buena prctica para separar las pruebas de integracin que dependen de
una base de datos en vivo desde el resto de las pruebas.
Es hora de ejecutar este Junit haciendo clic derecho en el caso de prueba y
seleccione 'Archivo Ejecutar' para ver si pasan las pruebas.

5.6. Resumen
Hemos completado la capa de persistencia y en la siguiente parte vamos a
integrarlo con nuestra aplicacin web. Pero primero, vamos a resumir rpidamente
el sombrero que hemos logrado en esta parte.

En primer lugar hemos configurado nuestra base de datos y scripts de

arranque creado.

Hemos creado guiones para utilizar al crear la tabla y tambin para

cargar algunos datos de prueba.

A continuacin hemos aadido algunas tareas en nuestro script para

ejecutar cuando necesitbamos para crear o eliminar la tabla y tambin


cuando tenamos que aadir los datos de prueba o borrar los datos.

Creamos la clase DAO real que controlar el trabajo de persistencia

utilizando de primavera SimpeJdbcTemplate .

Finalmente creamos unidad o con mayor precisin las pruebas de

integracin y las correspondientes tareas ant para ejecutar estas pruebas.


A continuacin se muestra una captura de pantalla de lo que su estructura de
directorios del proyecto debe ser similar despus de seguir las instrucciones
anteriores.

La estructura de directorios del proyecto al final de la parte 5

Captulo 6. La integracin de la aplicacin Web


con la Capa de Persistencia
Esta es la Parte 6 de una cuenta paso a paso de cmo desarrollar una aplicacin
web desde cero usando Spring Framework. En la Parte 1 hemos configurado el
entorno y establecer una aplicacin bsica. En la Parte 2 refinamos la aplicacin que
vamos a construir. Parte 3 aade toda la lgica y la unidad de pruebas de negocio
y la parte 4 desarroll la interfaz web. En la Parte 5 desarrollamos la capa de
persistencia. Ahora es el momento de integrar todo esto en una aplicacin web
completa.

6.1. Modificar capa de servicio


Si estructuramos nuestra aplicacin correctamente, slo tendramos que cambiar
las clases de capa de servicios para aprovechar la persistencia de base de datos.Las
clases de vista y el controlador no deberan tener que ser modificado, ya que deben
ser conscientes de los detalles de implementacin de la capa de servicio.As que
vamos a aadir la persistencia con la aplicacin ProductManager. Modificamos
el SimpleProductManager y aadir una referencia a un ProductDAO interfaz ms un
mtodo setter para esta referencia. Qu aplicacin realmente usamos aqu debera

ser irrelevante para la clase ProductManager, y vamos a establecer esto a travs de


una

opcin

de

configuracin. Tambin

cambiamos

los setProducts mtodo

un setProductDao mtodo para que podamos inyectar una instancia de la clase


DAO. El getProducts mtodo usar ahora el DAO para recuperar una lista de
productos. Por ltimo, el increasePrices mtodo ahora obtener la lista de productos
y despus el precio se ha incrementado el producto se almacena en la base de
datos utilizando el saveProduct mtodo en el DAO.
'Springapp / src / java / springapp / servicio / SimpleProductManager.java' :
springapp.service paquete;
java.util.List importacin;
springapp.domain.Product importacin;
springapp.repository.ProductDao importacin;
public class SimpleProductManager implementa ProductManager {
// Lista privada <productos> productos;
privada ProductDAO ProductDAO;
Lista pblico <Producto> getProducts () {
// Devolver productos;
volver productDao.getProductList ();
}
public void increasePrice (int porcentaje) {
Lista <productos> productos productDao.getProductList = ();
si (productos! = null) {
para (producto: productos) {
doble nuevoPrecio = product.getPrice (). doubleValue () *
(100 + porcentaje) / 100;
product.setPrice (nuevoPrecio);
productDao.saveProduct (producto);
}
}
}
public void setProductDao (ProductDAO ProductDAO) {
this.productDao = ProductDAO;
}
//

pblicas setProducts void (Lista <productos> productos) {

//
//

this.products = productos;
}

6.2. Fijar las pruebas fallan

Nosotros reescribimos la SimpleProductManager y ahora las pruebas, por supuesto,


un error. Tenemos que proporcionar la ProductManager con una implementacin en
memoria del ProductDAO . Nosotros realmente no queremos usar el verdadero DAO
aqu desde que nos gustara no tener que acceder a una base de datos para
nuestras

pruebas

unitarias. Vamos

aadir

una

clase

interna

llamada InMemoryProductDao que aferrarse a una lista de productos pf previstas en


el constructor. Esta clase en memoria tiene que ser aprobada en cuando creamos
un nuevo SimpleProductManager .
'Springapp / test / springapp / repositorio / InMemoryProductDao.java' :
springapp.repository paquete;
java.util.List importacin;
springapp.domain.Product importacin;
public class InMemoryProductDao implementa ProductDAO {
Lista privada <producto> Lista del producto;
InMemoryProductDao pblico (List <producto> Lista del producto) {
this.productList = Lista del producto;
}
Lista pblico <Producto> getProductList () {
devolver la lista de productos;
}
public void saveProduct (prod Producto) {
}
}
Y aqu est la modificados SimpleProductManagerTests :
'Springapp / test / springapp / servicio / SimpleProductManagerTests.java' :
springapp.service paquete;
java.util.ArrayList importacin;
java.util.List importacin;
springapp.domain.Product importacin;
springapp.repository.InMemoryProductDao importacin;
springapp.repository.ProductDao importacin;
junit.framework.TestCase importacin;
public class SimpleProductManagerTests extiende TestCase {
privada ProductManager SimpleProductManager;
Lista privada <Producto> productos;
private int PRODUCT_COUNT esttica = 2;
esttica CHAIR_PRICE privado Doble = new Double (20,50);
CHAIR_DESCRIPTION static String privada = "Presidente";
TABLE_DESCRIPTION static String privada = "Tabla";

esttica TABLE_PRICE privado Doble = new Double (150,10);


private int POSITIVE_PRICE_INCREASE esttica = 10;
void Protected Setup () throws Exception {
ProductManager = new SimpleProductManager ();
productos = new ArrayList <Producto> ();
// Stub una lista de productos
Producto = nuevo producto ();
product.setDescription ("Presidente");
product.setPrice (CHAIR_PRICE);
products.add (producto);
producto = nuevo producto ();
product.setDescription ("Tabla");
product.setPrice (TABLE_PRICE);
products.add (producto);
ProductDAO ProductDAO = InMemoryProductDao nuevas (productos);
productManager.setProductDao (ProductDAO);
//productManager.setProducts(products);
}
testGetProductsWithNoProducts public void () {
ProductManager = new SimpleProductManager ();
productManager.setProductDao (nueva InMemoryProductDao (nulo));
assertNull (productManager.getProducts ());
}
testGetProducts public void () {
Lista de productos> <= productos productManager.getProducts ();
assertNotNull (productos);
assertEquals (PRODUCT_COUNT, productManager.getProducts () size ().);
Producto = products.get (0);
assertEquals (CHAIR_DESCRIPTION, product.getDescription ());
assertEquals (CHAIR_PRICE, product.getPrice ());
producto = products.get (1);
assertEquals (TABLE_DESCRIPTION, product.getDescription ());
assertEquals (TABLE_PRICE, product.getPrice ());
}
testIncreasePriceWithNullListOfProducts public void () {
try {
ProductManager = new SimpleProductManager ();
productManager.setProductDao

(nueva

InMemoryProductDao

(nulo));
productManager.increasePrice (POSITIVE_PRICE_INCREASE);
}
capturas (NullPointerException ex) {
fallar ("Productos lista es nula.");

}
}
testIncreasePriceWithEmptyListOfProducts public void () {
try {
ProductManager = new SimpleProductManager ();
productManager.setProductDao (nueva InMemoryProductDao (new
ArrayList <Producto> ()));
//productManager.setProducts(new ArrayList <Producto> ());
productManager.increasePrice (POSITIVE_PRICE_INCREASE);
}
catch (Exception ex) {
fallar ("Productos lista est vaca.");
}
}
pblica testIncreasePriceWithPositivePercentage void () {
productManager.increasePrice (POSITIVE_PRICE_INCREASE);
doble expectedChairPriceWithIncrease = 22,55;
doble expectedTablePriceWithIncrease = 165,11;
Lista de productos> <= productos productManager.getProducts ();
Producto = products.get (0);
assertEquals (expectedChairPriceWithIncrease, product.getPrice ());
producto = products.get (1);
assertEquals (expectedTablePriceWithIncrease, product.getPrice ());
}
}
Tambin tenemos que modificar los InventoryControllerTests desde esa clase
tambin

utiliza

el SimpleProductManager . Aqu

est

modificadosInventoryControllerTests :
'Springapp / test / springapp / servicio / InventoryControllerTests.java' :
springapp.web paquete;
java.util.Map importacin;
java.util.ArrayList importacin;
org.springframework.web.servlet.ModelAndView de importacin;
springapp.domain.Product importacin;
springapp.repository.InMemoryProductDao importacin;
springapp.service.SimpleProductManager importacin;
springapp.web.InventoryController importacin;
junit.framework.TestCase importacin;
InventoryControllerTests clase pblica se extiende TestCase {
public void testHandleRequestView () throws Exception {
InventoryController controlador = new InventoryController ();

la

SimpleProductManager spm = new SimpleProductManager ();


spm.setProductDao (nueva InMemoryProductDao (new ArrayList
<Producto> ()));
controller.setProductManager (SPM);
//controller.setProductManager(new SimpleProductManager ());
ModelAndView ModelAndView = controller.handleRequest (null, null);
assertEquals ("hola", modelAndView.getViewName ());
assertNotNull (modelAndView.getModel ());
Mapa modelMap = (Mapa) modelAndView.getModel () conseguir ("modelo.");
Cadena nowValue = (String) modelMap.get ("ahora");
assertNotNull (nowValue);
}
}

6.3. Crear nuevo contexto de aplicacin para la


configuracin de capa de servicio
Vimos anteriormente que era bastante fcil de modificar la capa de servicio para
utilizar la persistencia de base de datos. Esto era debido a que se desacopla de la
capa web. Ahora es el momento para desacoplar o configuracin de la capa de
servicio de la capa web tambin. Vamos a eliminar la configuracin ProductManager
y la lista de productos del archivo de configuracin springapp-servlet.xml. Esto es lo
que este archivo se ve como ahora:
'Springapp / build / web / WEB-INF / springapp-servlet.xml' :
<? Xml version = "1.0" encoding = "UTF-8"?>
<frijoles 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 ">
<! - La definicin de contexto de aplicacin para la DispatcherServlet springapp
->
<Bean

id

clase

"MessageSource"

"org.springframework.context.support.ResourceBundleMessageSource">
<Property name = "nombre base" value = "mensajes" />
</ Bean>
<Nombre del bean = clase "/ hello.htm" = "springapp.web.InventoryController">
<Property name = "ProductManager" ref = "ProductManager" />
</ Bean>

<Nombre

del

bean

clase

"/

priceincrease.htm"

"springapp.web.PriceIncreaseFormController">
<Property name = "sessionForm" value = "true" />
<Propiedad nombre = valor "CommandName" = "priceIncrease" />
<Propiedad

nombre

valor

"commandClass"

"springapp.service.PriceIncrease" />
<Property name = "validador">
<Bean class = "springapp.service.PriceIncreaseValidator" />
</ Property>
<Propiedad nombre = valor "FormView" = "priceincrease" />
<Property name = "successView" value = "hello.htm" />
<Property name = "ProductManager" ref = "ProductManager" />
</ Bean>
<Bean

id

clase

"ViewResolver"

"org.springframework.web.servlet.view.InternalResourceViewResolver">
<Propiedad

nombre

valor

"viewClass"

"org.springframework.web.servlet.view.JstlView"> </ property>


<Propiedad nombre = valor "prefijo" = "/ WEB-INF / jsp /"> </ property>
<Propiedad nombre = valor "sufijo" = ". Jsp"> </ property>
</ Bean>
</ Beans>
Todava tenemos que configurar la capa de servicio y haremos todo lo que en su
propio

archivo

de

contexto

de

aplicacin. Este

archivo

se

llama'applicationContext.xml' y se carga a travs de un oyente servlet que vamos a


definir en 'web.xml' . Todo frijol configurado en este nuevo contexto de aplicacin
estar disponible para hacer referencia de cualquier contexto servlet.
'Springapp / build / web / WEB-INF / web.xml' :
<? Xml version = "1.0" encoding = "UTF-8"?>
<Versin web-app = "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 ">
<Listener>
<Clase
org.springframework.web.context.ContextLoaderListener
clase>
</ Listener>
<Servlet>
<Servlet-name> springapp </ servlet-name>

listener>
</

oyente

de

<Servlet-class> org.springframework.web.servlet.DispatcherServlet </ servletclass>


<Load-on-startup> 1 </ load-on-startup>
</ Servlet>
<Servlet-mapping>
<Servlet-name> springapp </ servlet-name>
<Url-pattern> *. Htm </ url-pattern>
</ Servlet-mapping>
<Welcome-file-list>
<Welcome-file>
index.jsp
</ Welcome-file>
</ Welcome-file-list>
<Jsp-config>
<Taglib>
<Taglib-uri> / primavera </ uri-taglib>
<Taglib-location> /WEB-INF/tld/spring-form.tld </ taglib-location>
</ Taglib>
</ Jsp-config>
</ Web-app>
Ahora vamos a crear un nuevo 'applicationContext.xml' archivo en la 'web / WEBINF " directorio ".
'Springapp / build / web / WEB-INF / applicationContext.xml' :
<? Xml version = "1.0" encoding = "UTF-8"?>
<frijoles xmlns = "http://www.springframework.org/schema/beans"
xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns: AOP = "http://www.springframework.org/schema/aop"
xmlns: tx = "http://www.springframework.org/schema/tx"
xsi: schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd ">
<! - La definicin de contexto de aplicacin de los padres para la aplicacin
springapp ->
<Bean

id

clase

"ProductManager"

"springapp.service.SimpleProductManager">
<Property name = "ProductDAO" ref = "ProductDAO" />
</ Bean>
<Bean id = clase "ProductDAO" = "springapp.repository.JdbcProductDao">

<Property name = "dataSource" ref = "dataSource" />


</ Bean>
</ Beans>

6.4. Aadir configuracin de transaccin y


agrupacin de conexiones de contexto de
aplicacin
Cada vez que persisten los datos en una base de datos a su alcance para utilizar las
transacciones para garantizar que todas las actualizaciones son realizar o no se
han completado. Usted quiere evitar tener la mitad de sus actualizaciones
persistieron mientras que la otra mitad no. Primavera ofrece una extensa gama de
opciones para la forma de proporcionar la gestin de transacciones. El manual de
referencia cubre esto en profundidad. Aqu vamos a hacer uso de una forma de
proporcionar esta usando AOP (Aspect Oriented Programming) en forma de un
consejo de transaccin y un punto de corte ApectJ para definir dnde deben
aplicarse las transacciones. Si usted est interesado en cmo funciona esto en ms
profundidad, eche un vistazo al manual de referencia. Estamos utilizando el nuevo
soporte de espacio de nombre introducido en la primavera de 2,0. El "AOP" y
espacios de nombres "TX" hacen las entradas de configuracin mucho ms concisa
en comparacin con la forma tradicional utilizando "<bean>" entradas regulares.
<Bean id = "transactionManager"
class

"org.springframework.jdbc.datasource.DataSourceTransactionManager">
<Property name = "dataSource" ref = "dataSource" />
</ Bean>
<AOP: config>
<AOP: asesor pointcut = "ejecucin (. * * * ProductManager .. (..))" consejoref = "txAdvice" />
</ AOP: config>
<Tx: id consejos = "txAdvice">
<Tx: Atributos>
<Tx: nombre del mtodo = "salvar *" />
<Tx: nombre del mtodo = "*" slo lectura = "true" />
</ Tx: atributos>
</ Tx: consejos>
El

punto

de

corte

se

aplica

cualquier

mtodo

llamado

en

la

interfaz

ProductManager. El consejo es un consejo transaccin que se aplica a los mtodos


con un nombre empezando por "salvar". Los atributos de transaccin por defecto de

REQUERIDA aplica desde que se especifica ningn otro atributo. El consejo tambin
se aplica transacciones "de slo lectura" en cualquier otro mtodo que se aconsej
a travs del punto de corte.
Tambin tenemos que definir una agrupacin de conexiones. Estamos utilizando la
agrupacin de conexiones DBCP del proyecto Apache Jakarta. Estamos reutilizando
el '' jdbc.properties archivo que hemos creado en la Parte 5.
<Bean id = clase "dataSource" = "org.apache.commons.dbcp.BasicDataSource"
destruye-method = "close">
<Propiedad

nombre

valor

"driverClassName"

"$

{jdbc.driverClassName}" />
<Propiedad nombre = valor "url" = "$ {jdbc.url}" />
<Propiedad nombre = valor "nombre de usuario" = "$ {jdbc.username}" />
<Propiedad nombre = valor "password" = "$ {jdbc.password}" />
</ Bean>
<Bean id = "propertyConfigurer"
class

"org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<Property name = "ubicaciones">
<Lista>
<Valor> classpath: jdbc.properties </ value>
</ List>
</ Property>
</ Bean>
Para que todo esto funcione necesitamos algunos archivos jar adicionales estn
presentes en el directorio 'Bibliotecas'. Si no existen, copie aspectjweaver.jar del '/
lib / aspectj 2.5 de primavera-marco' directorio y commons-dbcp.jar y commonspool.jar del 'marco de primavera-2.5 / lib / jakarta-commons ' directorio para
el'directorio' Bibliotecas.
Aqu est la versin final de nuestra 'applicationContext.xml' archivo:
'Springapp / build / web / WEB-INF / applicationContext.xml' :
<? Xml version = "1.0" encoding = "UTF-8"?>
<frijoles xmlns = "http://www.springframework.org/schema/beans"
xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns: AOP = "http://www.springframework.org/schema/aop"
xmlns: tx = "http://www.springframework.org/schema/tx"
xsi: schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd ">
<! - La definicin de contexto de aplicacin de los padres para la aplicacin
springapp ->
<Bean

id

clase

"ProductManager"

"springapp.service.SimpleProductManager">
<Property name = "ProductDAO" ref = "ProductDAO" />
</ Bean>
<Bean id = clase "ProductDAO" = "springapp.repository.JdbcProductDao">
<Property name = "dataSource" ref = "dataSource" />
</ Bean>
<Bean id = clase "dataSource" = "org.apache.commons.dbcp.BasicDataSource"
destruye-method = "close">
<Propiedad

nombre

valor

"driverClassName"

"$

{jdbc.driverClassName}" />
<Propiedad nombre = valor "url" = "$ {jdbc.url}" />
<Propiedad nombre = valor "nombre de usuario" = "$ {jdbc.username}" />
<Propiedad nombre = valor "password" = "$ {jdbc.password}" />
</ Bean>
<Bean id = "propertyConfigurer"
class

"org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<Property name = "ubicaciones">
<Lista>
<Valor> classpath: jdbc.properties </ value>
</ List>
</ Property>
</ Bean>
<Bean id = "transactionManager"
class

"org.springframework.jdbc.datasource.DataSourceTransactionManager">
<Property name = "dataSource" ref = "dataSource" />
</ Bean>
<AOP: config>
<AOP: asesor pointcut = "ejecucin (. * * * ProductManager .. (..))" consejoref = "txAdvice" />
</ AOP: config>
<Tx: id consejos = "txAdvice">
<Tx: Atributos>
<Tx: nombre del mtodo = "salvar *" />
<Tx: nombre del mtodo = "*" slo lectura = "true" />
</ Tx: atributos>

</ Tx: consejos>


</ Beans>

6.5. Prueba final de la solicitud completa


Ahora es el tiempo para ver si todas estas piezas trabajarn juntos. Construir y
desplegar su aplicacin terminada y recuerde tener la base de datos en
funcionamiento. Esto es lo que debera ver cuando se apunta el navegador web en
la aplicacin despus de que haya vuelto a cargar:

La solicitud completa
Se ve de la misma manera como lo hizo antes. Hicimos aadir persistencia, as que
si usted cierra la aplicacin no se perdern los aumentos de precios. Todava estn
all cuando se inicia la aplicacin copia de seguridad.
Una gran cantidad de trabajo para una aplicacin muy sencilla, pero nunca fue
nuestro objetivo de simplemente escribir esta aplicacin. El objetivo era mostrar
cmo ir sobre la creacin de una aplicacin Spring MVC desde cero y sabemos que
las aplicaciones que se crean son mucho ms complejos. Los mismos pasos se
aplican sin embargo y esperamos que haya adquirido los conocimientos suficientes
para que sea ms fcil para empezar a utilizar la primavera.

6.6. Resumen
Hemos completado las tres capas de la aplicacin - la capa de Web, la capa de
servicio y la capa de persistencia. En esta ltima parte nos reconfiguramos la
aplicacin.

Primero modificamos la capa de servicio para utilizar la ProductDAO.

A continuacin, tuvimos que arreglar algunas pruebas de servicio y la

capa web fallan.

A continuacin se introdujo un nuevo applicationContext separar la

configuracin de capa de servicios y la persistencia de la configuracin de la


capa web.

Tambin definimos algunas gestin de transacciones para la capa de

servicio y configuramos un pool de conexiones para las conexiones de base


de datos.

Finalmente construimos la aplicacin reconfigurado y probamos que

an funcionaba.
A continuacin se muestra una captura de pantalla de lo que su estructura de
directorios del proyecto debe ser similar despus de seguir las instrucciones
anteriores.

La estructura de directorios del proyecto al final de la parte 6

Referencias:
https://sites.google.com/site/springmvcnetbeans/step-by-step/
http://www.uv.es/grimo/teaching/SpringMVCv4PasoAPaso/index.html (spring
tool)

Apndice A. Referencias
Versin original de este tutorial basado en Eclipse y Tomcat.

http://www.springframework.org/docs/Spring-MVC-step-bystep/index.html
NetBeans IDE 6.0 Descargar

http://download.netbeans.org/netbeans/6.0/final/
Primavera Netbeans Mdulo Release 1.1

http://spring-netbeans.sourceforge.net/
GlassFish V2 UR1

https://glassfish.dev.java.net/downloads/v2ur1-b09d.html
Descarga springapp NetBeans Proyecto para los impacientes

http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?
pluginid=5171

Anda mungkin juga menyukai