Este documento presenta un proyecto de fin de carrera sobre la programación de una tienda virtual en Grails. Introduce brevemente Groovy como lenguaje de programación y Grails como framework web, y explica los objetivos generales y específicos del proyecto como el estudio de estas tecnologías y la creación de una aplicación de e-commerce para compararla con otro ejemplo. Además, detalla la organización de la memoria en diferentes capítulos sobre introducción, antecedentes, análisis, diseño, implementación, conclusiones y anexos.
Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Programacion de una tienda virtual en Grails
1. Treball fi de carrera
ENGINYERIA TÈCNICA EN
INFORMÀTICA DE SISTEMES
Facultat de Matemàtiques
Universitat de Barcelona
PROGRAMACIÓN DE UNA TIENDA VIRTUAL
EN GRAILS
Gabriel Bermúdez Merino
Director: Jesús Cerquides Bueno
Realitzat a: Departament de Matemàtica
Aplicada i Anàlisi. UB
Barcelona, 3 de julio de 2008
2. Índice detallado
1. Introducción...........................................4
1.1 Ámbito del proyecto..............................4
1.2 Objetivos generales..............................5
1.3 Objetivos específicos............................5
1.4 Organización de la memoria.......................6
2. Antecedentes...........................................7
2.1 Exposición de problemáticas......................7
2.1.1 Groovy como lenguaje de programación......7
2.1.2 Grails como framework Web.................9
2.2 Tecnologías asociadas...........................11
2.2.1 Groovy...................................11
2.2.2 Grails...................................16
2.3 Conclusión......................................21
3. Análisis..............................................23
3.1 Descripción del problema........................23
3.2 Descripción del producto........................23
3.3 Requisitos funcionales..........................23
3.3.1 Banner...................................24
3.3.2 Navigation Blocks........................24
3.3.3 Render...................................25
3.4 Requisitos no funcionales.......................25
3.5 Identificación de actores y objetivos...........26
4. Diseño................................................27
4.1 Casos de uso....................................27
4.1.1 Objetivos afines.........................27
4.1.2 Objetivos administrador..................31
4.1.3 Objetivos Usuario Registrado.............33
4.1.4 Objetivos Usuario No Registrado..........35
4.2 Diagramas.......................................35
4.2.1 Diagrama de dominio......................36
4.2.2 Modelo Vista-Controlador.................36
4.2.2.1 Vista-Controlador User............36
4.2.2.2 Vista-Controlador Pet.............37
4.2.2.3 Vista-Controlador Cart............37
4.2.3 Site Maps................................38
5. Implementación y pruebas..............................40
5.1 Entorno de desarrollo...........................40
5.1.1 GNU/Linux................................40
5.1.2 Gedit....................................40
5.1.3 Mozilla Firefox 2.14.....................40
5.1.4 Groovy...................................40
5.1.5 Grails...................................40
5.2 Seguimiento y problemáticas.....................41
5.2.1 Estructura y persistencia................41
5.2.2 Controladores y vistas...................44
5.2.2.1 Controladores.....................44
5.2.2.2 Vistas............................50
5.2.3 Extras...................................53
5.2.3.1 Tools Navigation Block............53
5.2.3.2 Contact Navigation Block..........54
5.2.3.3 Gsp’s estructura por defecto......55
3. 5.2.3.4 Imágenes..........................55
5.3 Pruebas.........................................56
6. Conclusiones y líneas de futuro.......................60
7. Bibliografía..........................................62
7.1 Libros..........................................62
7.2 Recursos electrónicos...........................62
8. Anexos................................................63
8.1 Manual instalación de librerías.................63
8.1.1 Groovy...................................63
8.1.2 Grails...................................63
8.2 Riesgos.........................................64
8.3 Análisis del tiempo de realización del proyecto.64
8.4 Implantación....................................66
4. Programación de una tienda virtual en Grails 1. Introducción
1. Introducción
1.1 Ámbito del proyecto
En la actualidad, Internet está viviendo una profunda
transformación: ha pasado de ser un escaparate de información
estática a un conjunto de aplicaciones y portales que utilizan
el conocimiento colectivo para facilitar servicios interactivos
donde los usuarios tienen el control de sus datos y de la
información.
Los entornos colaborativos son el conjunto de herramientas y
tecnologías sobre los que se sustenta la Web 2.0: en una sola
palabra "COLABORAR".
Hay varios factores que son responsables de que seamos testigos
de una convergencia entre tecnología y sociedad, donde la
tecnología facilita cambios sociales, y estos a su vez marcan
las tendencias de la tecnología. Uno de los factores más
importantes ha sido la facilidad de acceso y aparición de
tarifas planas de conexión, además de que la realidad de los
consumidores ha mutado y no se basa en una lealtad ciega hacia
cierta marca.
El ámbito de los entornos colaborativos es tan amplio como la
propia WWW. Su aplicación se extiende a cualquier modelo de
negocio, por lo que no es difícil imaginar el importante impacto
económico y social que suponen en el entorno empresarial actual.
La aparición de Blogs, Wikis, Redes sociales, Comercio
Electrónico, etc ... ha impulsado la proliferación de estándares
con el fin de ayudar a la creación de aplicaciones web, los
denominados frameworks, con un único objetivo: simplificar la
complejidad de la creación de aplicaciones web. Existen varios
frameworks web, Struts / Tapestry / ASP.NET / Ruby on Rails /
Groovy on Grails, pero casi todos basados en el mismo tipo de
estructura: J2EE.
Con el paso del tiempo cada vez es más sencillo utilizar estos
frameworks, por lo que la creación de una aplicación web,
actualmente, está al alcance de cualquier persona con nociones
básicas de programación y, sobretodo, curiosidad.
En algunas de las asignaturas de la carrera hemos estudiado
diversas metodologías de desarrollo de aplicaciones, incluyendo
su análisis y diseño, y su aplicación en el panorama
colaborativo de Internet actual. En este proyecto se volverán a
utilizar estas metodologías para crear una aplicación web de
e-commerce con el objetivo de demostrar la potencia del
framework web estudiado.
Gabriel Bermúdez Merino 4
5. Programación de una tienda virtual en Grails 1. Introducción
1.2 Objetivos generales
El objetivo principal de nuestro proyecto es el estudio del
nuevo framework web Grails basado en Groovy, para ello
utilizamos dicho framework para crear una aplicación de e-
commerce, en concreto una tienda virtual de mascotas basada en
un ejemplo de Sun Microsystems. Gracias a esta aplicación de
e-commerce se comparara la simplicidad de creación y la
eficiencia entre dicha aplicación y el ejemplo de Sun, con el
único objetivo de dar a conocer la potencia de este nuevo
framework, que sin duda alguna en el futuro dará mucho que
hablar en el panorama del diseño web.
1.3 Objetivos específicos
Los objetivos específicos que se quieren conseguir en el
proyecto son descritos a continuación:
• Estudio de Groovy, el lenguaje de programación base de
Grails. Para este estudio seguiremos las siguientes fases:
o Estudio base de las diferencias más relevantes entre
Groovy y Java.
o Introducción a los comandos básicos de Groovy.
o Realización de ejemplos para profundizar en su
estructura.
• Estudio de Grails, tanto su estructura como sus posibles
aplicaciones. Para este estudio seguiremos las siguientes
fases:
o Introducción a la estructura de Grails y sus comandos
más relevantes.
o Realización de ejemplos simples para profundizar en
su estructura.
o Realizar un ejemplo que estudia en profundidad la
gran mayoría de su estructura y comandos.
o Comparación entre este framework y la estructura del
de Sun Microsystems.
Gabriel Bermúdez Merino 5
6. Programación de una tienda virtual en Grails 1. Introducción
1.4 Organización de la memoria
La memoria esta organizada en diversos capítulos, cada uno con
sus funcionalidades, las cuáles están explicadas a continuación:
• Introducción: Apartado en el que se hace una aproximación
a los términos que acatará el proyecto.
• Antecedentes: Se expondrá el problema que se quiere
abordar con el proyecto y se estudiarán las tecnologías
para llevarlo a cabo.
• Análisis: En este apartado analizaremos el problema, la
aplicación que queremos desarrollar, sus requisitos y
demás objetivos que se quieren abordar.
• Diseño: En este apartado se diseñara el sistema según las
especificaciones analizadas en el apartado anterior.
• Implementación y pruebas: Este apartado será escrito
durante la implementación del código y en él explicaremos
el entorno con el que desarrollaremos la aplicación, las
simulaciones y problemáticas.
• Conclusiones y Líneas de Futuro: El apartado de
conclusiones será escrito antes de finalizar el proyecto y
en el haremos la valoración final de la aplicación y del
proyecto, así también evaluaremos las líneas de futuro de
éste.
• Bibliografía: En la bibliografía especificaremos los
recursos de dónde se ha extraído la información necesaria
para el desarrollo del proyecto.
• Anexos: Los anexos contienen toda la documentación técnica
e instalación de librerías necesarias, así como un
análisis del tiempo de realización el proyecto.
Gabriel Bermúdez Merino 6
7. Programación de una tienda virtual en Grails 2. Antecedentes
2. Antecedentes
2.1 Exposición de problemáticas
En los últimos años Internet ha ido evolucionando poco a poco
hacia un entorno colaborativo entre usuarios, hasta llegar a la
actualidad y a la Web 2.0, donde el entorno colaborativo ha
culminado con la aparición de Blogs, Wikis, el e-commerce, …
Esto último implica el estudio e investigación de nuevas
tecnologías que hagan más sencillo el desarrollo de nuevas
aplicaciones web tanto para el desarrollador como para el
usuario llano.
El desarrollo de frameworks web ha ido evolucionando
constantemente, desde los struts, framework que implementa el
patrón de arquitectura Modelo Vista-Controlador en Java, hasta,
por ejemplo, “Groovy on Grails”, buscando siempre una
simplificación de código pero sin comprender una reducción de la
calidad del producto final.
El problema abordado por este proyecto es la creación de una
aplicación web de e-commerce, concretamente una tienda virtual
de mascotas, utilizando la nueva tecnología basada en Groovy,
Grails. Para la implementación de esta aplicación han sido
necesarios varios estudios previos de cada una de las
tecnologías que comprenden el mundo de “Groovy on Grails”, los
cuales podriamos dividir en:
• Estudio del lenguaje de programación Groovy
• Estudio del framework basado en Groovy, Grails
• Análisis, diseño e implementación de la aplicación web
propiamente dicha
2.1.1 Groovy como lenguaje de programación
El 2 de Enero de 2007 aparecía la
versión 1.0 de Groovy, un nuevo lenguaje
de programación orientado a objetos
desarrollado por Guillaume Laforge, Jefe
de Proyecto y JSR-241 Spec Lead.
La implementación de Groovy se realiza sobre la plataforma Java,
además, tiene características similares a Python, Ruby, Perl y
Smalltalk. Gracias a la especificación JSR-241, se busca su
estandarización para una futura inclusión como componente
oficial de la plataforma Java.
Groovy utiliza una sintaxis muy parecida a Java, compartiendo el
mismo modelo de objetos, de hilos y de seguridad. Mediante
importaciones, Groovy puede acceder a todas las API de Java
ampliando la compilación, ya que el bytecode generado es
totalmente compatible con el que Java genera para la Java
Virtual Machine.
Gabriel Bermúdez Merino 7
8. Programación de una tienda virtual en Grails 2. Antecedentes
Para Groovy, Java no es un lenguaje incompatible con su código,
todo lo contrario, todo el código escrito en Java es válido en
Groovy. Este aspecto hace su aprendizaje mucho más sencillo a
programadores Java que otros lenguajes que se ejecutan sobre la
Java Virtual Machine, como Jython o Jruby.
Java es totalmente compatible con Groovy, pero esto no hace que
Groovy pierda todas las ventajas de un lenguaje de scripting, ya
que también se puede ejecutar de forma dinámica. Por ejemplo, en
Java la salida estándar de “Hello World” hace necesaria la
escritura de una clase, un método main con una serie de
argumentos, etc… Pero en Groovy, no es necesario escribir todo
el código, te puedes ahorrar la declaración de la clase y el
método main, y sólo escribir una línea de código que muestre por
pantalla “Hello World”.
El contenido del archivo HelloWorld.groovy sería:
println “Hello World”
Como podemos observar, el dinamismo de un lenguaje de scripting
se encuentra presente en Groovy, pero, ¿y la compatibilidad con
Java?
Groovy da soporte a listas, mapas, etc… y aún podemos demostrar
la simplicidad de Groovy y su capacidad para ejecutar código en
Java:
//Printamos una fecha utilizando codigo Java
def mydate = new java.util.Date()
println mydate
//Iteración sobre un hash map
def numbersMAP = ['1':'ONE', '2':'TWO']
for (entry in numbersMAP) {
println "${entry.key} = ${entry.value}"
}
//Introducimos un rango
def range = 'a'..'d'
//Listas
def numberlist = [1, 2, 3, 4, 5, 6, 7, 8]
println numberlist;
println "Maximum value: ${numberlist.max()}"
Como podemos observar en el código, utilizamos directamente
java.util.Date y no importamos un soporte para colecciones para
trabajar con listas, mapas y rangos. Aunque no es necesario,
Gabriel Bermúdez Merino 8
9. Programación de una tienda virtual en Grails 2. Antecedentes
como en el ejemplo, podemos exportar librerías Java para que el
proceso de desarrollo sea más cómodo.
En el apartado de tecnologías asociadas, profundizaremos más en
el mundo de Groovy mediante explicaciones y ejemplos.
2.1.2 Grails como framework Web
Grails es un framework para
aplicaciones Web de libre
distribución, que tiene como
base el lenguaje de
programación Groovy. Grails
es un framework de alta productividad que viene distribuido bajo
el paradigma del “código por convención” (MVC), el cuál
proporciona un entorno de desarrollo independiente y unos
detalles de configuración escondidos para el desarrollador.
Grails se llamó previamente “Groovy on Rails” (nombre que se le
puso en como homenaje a David Heinemeier Hansson, fundador de
Ruby on Rails, otro framework web). El trabajo de desarrollo
comenzó en Julio de 2005 que dio como fruto la versión 0.1 el 29
de Marzo de 2006 i la versión 1.0 el 18 de Febrero de 2008.
En el momento de su implementación, se estudiaron varios
conceptos a favor de Grails entre los que destacaban:
• Proporcionar una alta productividad basándose en la
plataforma de Java.
• Utilizar de manera más simple tecnologías de Java como
Hibernate y Spring, mediante una interface consistente.
• Un framework sencillo y fácil de aprender.
• Documentación con participación de los usuarios.
• Proporcionar simplicidad en áreas donde antes solo podían
adentrarse usuarios expertos:
o Framework persistente potente y consistente.
o Uso sencillo pero potente de las templates de vista
utilizando GSP (Páginas de Servidor Groovy).
o Librerías de tags dinámicas para una creación de
componentes web sencilla.
o Buen soporte a Ajax pero simple de ampliar y
personalizar.
• Proporcionar ejemplos de aplicaciones con los que
demostrar la potencia de este nuevo framework.
• Proporcionar un modo de desarrollo completo, incluyendo un
servidor web y un sistema de carga de ficheros automática.
Gabriel Bermúdez Merino 9
10. Programación de una tienda virtual en Grails 2. Antecedentes
Dichos objetivos se han conseguido en mayor o menor grado, entre
los logros más relevante, cabe destacar:
• Framework sencillo y simple
Gracias a la implementación de Grails basandose en el
paradigma del “código por convención” (MVC), se han
conseguido realizar nuevas implementaciones, ya sea en la
mejora del código o en su funcionalidad. Las más relevantes
son:
o Controllers
Los controllers son los sustitutos naturales de los
Servlets tal y como los conocemos, ya que siguiendo la
convención de Grails crearemos una Closure de Groovy
cada vez que queramos realizar una acción sobre una
clase de la aplicación web.
La creación de un controlador vendría dado por:
$> groovy create-controller
----------------------------------------------------
def list = {
if(!params.max) params.max = 10
[ petList: Pet.list( params ) ]
}
o Soporte a Ajax y uso de librerías dinámicas para
poder implementar plugins con el fin de facilitar la
implementación de la nueva aplicación web.
• Persistencia y alta productividad
o La alta productividad viene dada por el uso del
lenguaje de scripting Groovy como base de
programación, ya que sobre este lenguaje se podría
aplicar un famoso dicho, “Nunca tan poco a dado
tanto”, ya que con poca cantidad de código se puede
realizar una pequeña aplicación en Grails.
o La persistencia en Grails viene dada por la
simplicidad de creación de sus clases de dominio:
$> groovy create-domain-class
----------------------------------------------------
class Cart {
String status
String payment
String numberTarget
Float total
Map contentBuy=[1 : 1]
}
Gabriel Bermúdez Merino 10
11. Programación de una tienda virtual en Grails 2. Antecedentes
seguida por la implementación del soporte más
importante para las operaciones CRUD (Create, Read,
Update, Delete), el Scaffolding.
Scaffolding es un método para construir aplicaciones
basadas en bases de datos, esta técnica está
soportada por algunos frameworks del tipo MVC en el
cuál el programador escribe una especificación que
describe cómo debe ser usada la base de datos. Luego
el compilador utiliza esa especificación para generar
el código que la aplicación usará para crear, leer,
actualizar y eliminar registros de la base de datos.
En Grails la activación del Scaffolding es tan
sencilla como la mayoría de implementaciones en
Grails.
class cartController {
scaffold = true
}
Como podemos observar, Grails es un framework potente pero a la
par sencillo, ahora sólo hemos nombrado los aspectos más
relevantes por lo que a continuación, en el apartado de
tecnologías asociadas, profundizaremos más en el mundo de Grails
mediante explicaciones y ejemplos, posteriormente realizaremos
una implementación completa de una aplicación web de e-comerce.
2.2 Tecnologías asociadas
2.2.1 Groovy
En este apartado, se va a profundizar en los aspectos más
relevantes de Groovy mediante descripciones y ejemplos. No se
puede considerar este apartado como un manual de usuario de
Groovy, más bien como un pequeño tutorial de introducción a
éste potente lenguaje de scripting.
En algunos de estos ejemplos se hará una comparativa directa con
Java con el objetivo de demostrar la disminución de código entre
uno y otro.
1. Primeros pasos: “Hola Mundo”
Queremos que Groovy imprima por pantalla una cadena de
caracteres con la información “Hola Mundo”. Gracias a la
compatibilidad de Groovy con el lenguaje Java se podría
implementar este problema de la misma manera que lo
haríamos en Java, pero al ser un lenguaje de Scripting no
sería necesaria la creación de una clase, con solo
introducir la instrucción de imprimir por pantalla sería
suficiente.
Gabriel Bermúdez Merino 11
12. Programación de una tienda virtual en Grails 2. Antecedentes
public class HolaMundo{
public static void main(String[] args){
System.out.println(“Hola Mundo”);
}
}
---------------------------------------------------------
println “Hola Mundo”
La diferencia de cantidad de código es abrumadora, pero
existen otras implementaciones con el mismo objetivo.
class HolaMundo{
def hiWorld(name){
“Hola ${name}”
}
}
def hW = new HolaMundo()
println hW.hiWorld(“Mundo”)
Con esta implementación podemos observar algunas de las
características de Groovy:
• El valor de retorno no es específico, por lo que
usamos la palabra reservada def (muy parecida a la
palabra var de JavaScript)
• No es necesario utilizar la palabra reservada return,
la última sentencia ejecutada determina el valor de
retorno.
• La cadena de caracteres no es un java.lang.string, se
trata de un GString. Los GStrings permiten la
evaluación de expresiones, al igual que con Perl.
2. Tipos de datos
Groovy soporta todos los tipos de datos de Java, sin
primitivos, y además define listas y mapas como tipos
básicos, así como los arrays y hashs de Perl y PHP. En
realidad las listas son en el fondo java.util.ArrayList y
los mapas java.util.HashMap, por lo que se podrán utilizar
todos los métodos ya conocidos en Java relacionados con
listas y mapas. Además, Groovy permite que los índices y
llaves sean manipulados a través del operador ‘[]’, y en el
caso de los mapas también mediante ‘.’.
<-- Números -->
def x = 12
def y = 10.0e4
<-- Caracteres y Strings -->
def c = “a”
def s = “hi World!”
<-- Listas y Mapas -->
def list = [1,2,3,4]
def map= [“Jon”:”Matthers”, “1”:”Mark”]
Gabriel Bermúdez Merino 12
13. Programación de una tienda virtual en Grails 2. Antecedentes
<-- Rangos -->
def rg = (0..9)
<-- Impresión de rangos -->
rg.each{num -> print num}
Como podemos observar, la definición de variables en
Groovy no implica una definición primitiva, el contenido
de la variable especifica el tipo de dicha variable. En la
última descripción, podemos observar el método de
recorrido de los rangos, el cuál puede ser aplicado en más
tipos de variables, además nos introduce en un nuevo
concepto de Groovy, que ha sido adoptado por la nueva
implementación de Java 7, las closures.
3. Closures
Una closure se podría describir como un bloque de código
reutilizable, que retiene la información entorno donde
fueron definidos.
Esta forma de trabajo es muy parecida a JavaScript, ya que
es muy parecido a la definición de una función anónima en
un script. Las closures pueden recibir parámetros, puesto
que los tipos de Groovy son opcionales, sólo es necesario
escribir el nombre del parámetro. El uso de closures es
tan común, que si no se ha definido un parámetro
específico de todos modos estará disponible una variable
it que representa el valor del parámetro.
def printOut = {item -> print item}
(0..9).each(printout)
---------------------------------------------------------
def printOut = {print it}
(0..9).each(printout)
La implementación de las closures implica un gran avance
en el mundo de la programación, ya que no es necesario
crear un nuevo método fuera del actual pudiendo utilizar
las variables locales del actual.
4. Expresiones regulares
Como muchos lenguajes de scripting, Groovy también ofrece
la posibilidad de utilizar expresiones regulares, es
decir, declarar y utilizar dichas expresiones sin
necesidad de construcciones complexas o añadir sintaxis
adicionales a las construcciones básicas del lenguaje.
Gabriel Bermúdez Merino 13
14. Programación de una tienda virtual en Grails 2. Antecedentes
Basta con declarar la expresión de búsqueda entre barras
diagonales y usar uno de los tres operadores disponibles:
• =~ búsqueda de ocurrencias
• ==~ coincidencias
• ~ patrón
def text = “At school, Harry had no one. Everybody know
that Dudley’s gang hated that odd Harry
Potter” + “ in his baggy old clothes and
broken glasses, and nobody liked to disagree
with Dudley’s gang.”
matcher = (text =~ /Harry Potter/)
---------------------------------------------------------
matcher = (text ==~ /Harry/)
---------------------------------------------------------
matcher = (text ~ /H.*y/)
5. POJOs to POGOs
En los últimos años Sun a dominado el sector de JavaBeans
gracias al resurgimiento de los POJOs (Plain Old Java
Objects), es decir, un subconjunto de la convención
JavaBeans. Los POJOs son un subconjunto puesto que los
JavaBeans deben notificar cualquier cambio que se realice
en alguna de sus propiedades, mientras que los POJOs no lo
hacen. Spring y Hibernate no dudaron sobre las ventajas de
uso, y no tardaron en incorporarlo en su implementación.
El único pero que tenían los POJOs era su complicada
implementación, este apartado fue resuelto gracias a que
algunos Ambientes de Desarrollo Integrados (IDE)
comenzaron a proporcionar herramientas para generar este
tipo de código.
Pero los POGOs van más allá, simplemente con declarar las
propiedades según la convención, los métodos de acceso se
generarán. Dichas propiedades se declaran con tipo y
nombre, sin modificador de acceso, ya que de tenerlo dejan
de ser una propiedad para pasar a ser un campo.
La creación de POGOs implica una definición de un POGO
propiamente dicho, la definición de cómo mínimo 1
propiedad y campos. En el momento de la creación
descubrimos otra de las ventajas de Groovy, en el momento
de la llamada al constructor mediante un mapa extendido
debido a que Groovy anexa un constructor por omisión a los
POGOs. En el momento del acceso a campos se puede realizar
mediante el operador ‘.’ o ‘[]’ lo cuál hace que parezca
que se ha roto la encapsulación del POGO, pero en realidad
es todo lo contrario, ya que existe la posibilidad de
Gabriel Bermúdez Merino 14
15. Programación de una tienda virtual en Grails 2. Antecedentes
obtener y modificar el valor de un campo mediante el
operador ‘.@’ que tampoco rompe la encapsulación.
class Person{
String name #Property
String firstName #Property
private int id #Field
String toString() {“${name} ${firstName}”}
}
Person person = new Person(name:’Matthew’,
firstName:’McMag’)
assert “Matthew McMag” == person.toString()
person.firstName = “McGam”
assert “Matthew McGam” == person.toString()
person[‘firstName’] = “McMag”
assert “Matthew McMag” == person.toString()
assert person.name == “Matthew”
assert person.@name == “Matthew”
assert person.completName == “Matthew McMag”
try{
assert person.completName == “Matthew McMag”
}match(MissingFieldException e){
println “Error, completName isn’t a field
}
Gracias a los POGOs podemos descubrir otra de las
peculiaridades de Groovy, es el segundo lenguaje, después
de Java, que soporta anotaciones, aunque el soporte para
tipos genéricos aún está en desarrollo.
class Person{
@BoundProperty String name
@BoundProperty String firstName
}
6. Desarrollo web con Groovy
Como pequeña introducción en el desarrollo web con Groovy
antes de las definiciones y ejemplos de Grails,
introduciremos el sustituto de los Servlets de Java por
los Groovlets. La simplicidad de código y la posible
inclusión de tags de html en el mismo código en Groovy
representa grandes ventajas que los Servlets no disponen.
A continuación introducimos un ejemplo de un Groovlet ya
que es la forma más sencilla de entender este tipo de
implementación.
Gabriel Bermúdez Merino 15
16. Programación de una tienda virtual en Grails 2. Antecedentes
import java.util.Date
if (session == null) {
session = request.getSession(true);
}
if (session.counter == null) {
session.counter = 1
}
println """
<html>
<head>
<title>Groovy Servlet</title>
</head>
<body>
Hello, ${request.remoteHost}: ${session.counter}! ${new
Date()}
</body>
</html>
"""
session.counter = session.counter + 1
2.2.2 Grails
En este apartado, se va a profundizar en los aspectos más
relevantes de Grails mediante descripciones y ejemplos. No se
puede considerar este apartado como un manual de usuario de
Grails, más bien como un pequeño tutorial de introducción a
éste potente framework web.
En los siguientes apartados vamos a tratar varios aspectos de
Grails, desde su estructura hasta llegar a su funcionalidad
pasando por la implementación de controladores, gsp’s, etc …
1. Estructura de la aplicación
El primer paso en la implementación de un nuevo proyecto
en Grails, es la creación de la estructura de directorios
del proyecto. Para realizar este paso, Grails
nos proporciona un comando que nos crea
automáticamente la estructura de directorios:
$> grails create-app
seguidamente a esta instrucción introducimos el
nombre de la aplicación y a continuación Grails
nos crea la estructura necesaria para
administrar nuestro proyecto.
Una de las ideas principales de Grails es la
aplicación de convenciones de desarrollo de
aplicaciones Web, siguiendo esta convención se
crean los archivos y directorios que se usarán
en la mayoría de aplicaciones Web. Aunque esta
estructura de directorios no es estática, ya que
la podemos configurar según nuestras
necesidades.
Gabriel Bermúdez Merino 16
17. Programación de una tienda virtual en Grails 2. Antecedentes
Esta estructura de ficheros nos sitúa automáticamente los
Paths donde van a ir almacenados las vistas,
controladores, librerías,… donde Grails va a ir colocando
los nuevos elementos que se vayan creando automáticamente
durante la implementación del proyecto.
Si se tiene experiencia utilizando Apache Ant, se puede
crear manualmente este sistema de directorios modificando
el archivo de /src/grails/build.xml que encontramos en el
directorio GRAILS_HOME.
2. Base de datos
La base de datos que viene configurada por defecto cuando
creamos un nuevo proyecto en Grails es volátil y utiliza
el lenguaje de base de datos HSQL. Si queremos que nuestra
base de datos deje de ser volátil y queremos que tenga una
permanencia (en el localhost), se modificará la siguiente
línea en el fichero:
…/grails-app/conf/ApplicationDataSource.groovy
dataSource {
pooled = false
driverClassName = "com.mysql.jdbc.Driver"
username = "root"
password = ""
}
…
environments {
development {
dataSource {
dbCreate = "update" // one of 'create',
'create-drop','update'
url = "jdbc:mysql://localhost/petStore_dev"
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:mysql://localhost/petStore_test"
}
}
production {
dataSource {
dbCreate = "update"
url =
"jdbc:mysql://localhost/petStore_prod;shutdown=true"
}
}
}
Como podemos observar en el código, modificando el valor
de dbCreate por update, establecemos una base de datos
permanente. Observamos también que por cada tipo de
implementación, ya sea de desarrollo, testeo o producción
podemos tener una base de datos diferente, lo que facilita
la futura implantación del proyecto.
Si por comodidad se quiere utilizar otro tipo de lenguaje
de base de datos, tan sólo se ha de descargar el driver
correspondiente y almacenarlo en el directorio lib del
Gabriel Bermúdez Merino 17
18. Programación de una tienda virtual en Grails 2. Antecedentes
proyecto. Seguidamente se ha de modificar el nombre del
driver en el anterior código, así como la situación de las
bases de datos que se utilizaran.
3. Clases de dominio
El Mapeo de Objetos Relacionales de Grails (GORM) utiliza
internamente Hibernate 3, pero para poder implementar la
aplicación Web no es necesario tener ningún conocimiento
sobre Hibernate. Para realizar este mapeo Grails utiliza
las llamadas clases de dominio, que determina los objetos
mapeados en la base de datos. Se pueden linkar clases de
dominio utilizando relaciones proporcionando metodos
dinámicos para realizar operaciones CRUD (Create, Read,
Update, Delete), sobretodo mediante Scaffolding.
Grails dispone de una instrucción para la creación
automática de clases, que nos almacenará las nuevas clases
en el directorio …/grails-app/domain/ ,
$> grails create-domain-class
a dicha instrucción solamente le hemos de proporcionar el
nombre de la clase y ya tendremos una nueva clase
disponible para configurar.
Estas clases de dominio pueden disponer, además de sus
propiedades y campos, de métodos propios y declaraciones
de constraints para las propiedades y campos. Es posible
establecer una relación de 1-1, 1-n o n-n entre clases
directamente en la implementación de dichas clases, este y
anteriores elementos los veremos en el siguiente ejemplo.
class Pet {
String name
String type
String description
Float price
byte[] image
static hasMany = [carts:Cart]
static belongsTo = Cart
static constraints = {
name(maxLength:50, blank:false)
type(inList:['Bird','Cat', 'Dog', 'Fish', 'Ferret',
'Rodent'], blank:false)
description()
price(min:0f)
image(nullable:true, maxSize:65536) /* 64K */
}
static mapping = {
description type: 'text'
}
}
Gabriel Bermúdez Merino 18
19. Programación de una tienda virtual en Grails 2. Antecedentes
En el anterior ejemplo descubrimos las ventajas de las
clases de dominio de Grails, las restricciones directas en
código y la relación entre diferentes clases directamente
en código.
• Restricciones directas en código
Como podemos observar, utilizando una closure con el
nombre “constraints”, podemos configurar las
restricciones que queremos que tengan las propiedades
y los campos de la clase, lo que nos facilitará la
implementación posteriormente cuando se creen las
vistas y los controladores.
• Relación entre clases directamente en código
Para realizar una relación entre clases, tan sólo se
ha de establecer una variable relacional:
o Sección 1 de la relación: Utilizaremos la
variable belongsTo con valor igual a la clase
con la que estamos relacionando.
o Sección n de la relación: Utilizaremos la
variable anterior belongsTo, además de la
variable hasMany con valor igual a la clase con
la que estamos relacionando mediante un mapa
extendido, especificando el nombre de la
variable que almacenará la colección de valores.
4. Controladores y vistas
Una vez que las clases de dominio ya se han creado, es el
momento de utilizar un nuevo comando de Grails que nos
auto genera los CRUD básicos para nuestra aplicación Web:
$> grails generate-all
Gracias a este comando se crean los llamados controladores
y las vistas básicas que necesitaremos para gestionar
nuestra clase de dominio.
Los controladores se almacenarán en el directorio grails-
appcontrollers. Dichos controladores son los responsables
de el manejo de las peticiones de nuestra aplicación Web.
Los controladores son los sustitutos naturales de los
Servlets de Java, con la ventaja de que su implementación
es tan sencilla como crear una closure por cada tipo de
petición que queramos que atienda. A continuación vamos a
ver un ejemplo de controladores e introduciremos el
concepto de Scaffolding en Grails.
Gabriel Bermúdez Merino 19
20. Programación de una tienda virtual en Grails 2. Antecedentes
class CartController {
def index = { redirect(action:list,params:params) }
def scaffold = Cart
def list = {
if(!params.max) params.max = 10
[ cartList: Cart.list( params ) ]
}
def show = {
def cart = Cart.get( params.id )
if(!cart) {
flash.message = "Cart not found with id ${params.id}"
redirect(action:list)
}
else { return [ cart : cart ] }
}
def delete = {
def cart = Cart.get( params.id )
if(cart) {
cart.delete()
flash.message = "Cart ${params.id} deleted"
redirect(action:list)
}
else {
flash.message = "Cart not found with id ${params.id}"
redirect(action:list)
}
}
def edit = {
def cart = Cart.get( params.id )
if(!cart) {
flash.message = "Cart not found with id ${params.id}"
redirect(action:list)
}
else {
return [ cart : cart ]
}
}
def update = {
def cart = Cart.get( params.id )
if(cart) {
cart.properties = params
if(!cart.hasErrors() && cart.save()) {
flash.message = "Cart ${params.id} updated"
redirect(action:show,id:cart.id)
}
else {
render(view:'edit',model:[cart:cart])
}
}
else {
flash.message = "Cart not found with id ${params.id}"
redirect(action:edit,id:params.id)
}
}
def create = {
def cart = new Cart()
cart.properties = params
return ['cart':cart]
}
def save = {
def cart = new Cart(params)
if(!cart.hasErrors() && cart.save()) {
flash.message = "Cart ${cart.id} created"
redirect(action:cartBuy,id:params.id)
}
else {
render(view:'create',model:[cart:cart])
}
}
}
Gabriel Bermúdez Merino 20
21. Programación de una tienda virtual en Grails 2. Antecedentes
En este ejemplo, podemos ver los controladores básicos que
se crean con el comando anterior, añadiendo además la
opción de Scaffolding con la variable “scaffold”.
Los controladores básicos son los de Creación,
Actualización, Edición y Modificación, pero posteriormente
se pueden ir añadiendo funcionalidades como el logging de
usuarios, etc...
Una vez el controlador ha procesado la petición, la delega
a la vista apropiada. Para realizarlo Grails utiliza un
mecanismo de convención, en el cuál el controlador delega
la petición a la vista que tiene su mismo nombre, la cuál
se encuentra almacenada en grails-app/views/name/ donde
name es el nombre de la clase dominio. En dicha carpeta
podemos encontrar la vista en formato JSP o GSP, ya que
Grails admite ambos formatos.
5. Funcionalidad
Grails incorpora un servidor de management con el que se
puede ejecutar nuestra aplicación de Grails antes de
importarla. Utilizando el comando especifico:
$> grails run-app
de compilación y ejecución con nuestra aplicación, el
servidor inicia nuestra aplicación en la dirección
http://localhost:8080/nameApp, donde “nameApp” es el
nombre de nuestra aplicación Web.
Posteriormente podemos exportar nuestra aplicación en un
fichero war para importarlo en un Tomcat utilizando el
comando:
$> grails war
Después de esta breve introducción a Grails, realizaremos una
aplicación Web de ejemplo basada en una tienda virtual de
mascotas, donde profundizaremos más en los aspectos de Grails
además de una comparación directa con la implementación de una
aplicación semblante en Java.
2.3 Conclusión
Durante el desarrollo de este apartado hemos visto los problemas
que tendremos que afrontar durante el desarrollo de proyecto,
además de un pequeño estudio de las tecnologías que utilizaremos
para el desarrollo de dicho proyecto. Los papeles de las
diferentes tecnologías en nuestro proyecto son:
Gabriel Bermúdez Merino 21
22. Programación de una tienda virtual en Grails 2. Antecedentes
• Groovy: Lenguaje de programación base de Grails, con
el que sin una pequeña práctica anterior al
desarrollo del proyecto, no se habría podido realizar
con soltura.
• Grails: Framework Web que nos asiste en la creación
de nuestra aplicación Web y además nos hace dicha
tarea más amena y sencilla.
Gabriel Bermúdez Merino 22
23. Programación de una tienda virtual en Grails 3. Análisis
3. Análisis
3.1 Descripción del problema
Tenemos la necesidad de crear un portal de una tienda virtual de
mascotas, donde los visitantes de dicha página pueden ver los
animales que hay en stock, así como sus descripciones y
posteriormente comprarlos si satisfacen sus necesidades previo
registro en la base de datos de la página.
Además de la visión externa del portal y las actividades que
podemos realizar en ella, necesitamos poder gestionar tanto los
pedidos como el stock de animales y el registro de usuarios,
mediante unas actividades especiales para el administrador de la
página.
3.2 Descripción del producto
El portal que desarrollaremos utilizará como apoyo el framework
Web Grails. En dicho portal, el cliente navegará por la lista de
mascotas a la venta y se autenticará en la página, previo
registro, para poder gestionar la compra de las mascotas que
desee, además de poder editar sus datos de registro y realizar
un seguimiento del estado de las compras que ha realizado
previamente.
El administrador del portal administrará la lista de usuarios,
mascotas y carritos de la compra. La creación de nuevas entradas
en las listas de usuarios, además de su edición, actualización y
eliminación; y la gestión de los carritos de la compra de los
clientes,, actualizando el estado de éstos según vaya
evolucionando el pedido.
3.3 Requisitos funcionales
En este apartado definiremos los requisitos funcionales y la
estructura fija de nuestro portal. En la siguiente figura
podemos ver los elementos básicos que tendrá nuestro portal.
Gabriel Bermúdez Merino 23
24. Programación de una tienda virtual en Grails 3. Análisis
3.3.1 Banner
El portal, como todo portal que se precie, tendrá un banner
estático en el que se mostrará su temática mediante una imagen
fija con la que se pueda relacionar fácilmente con la rama de
comercio a la que está dirigido el portal. Será una imagen fija,
sin opciones ni funciones añadidas.
3.3.2 Navigation Blocks
Tendremos dos bloques de navegación, el propio de navegación y
el de contacto.
• TOOLS NAVIGATION BLOCK
En este bloque de navegación, se proporcionarán diferentes
“atajos” a diferentes servicios del portal. Según el
usuario que se encuentre activo en la sesión, las opciones
del bloque de navegación variarán, ya que las opciones del
administrador tienen que ser diferentes a la del usuario
externo ya registrado o sin registrar. Las opciones que
tendrá cada usuario serán:
o ADMINISTRADOR
Pets administration: Acceso a la lista de
mascotas dadas de alta en la página, donde
además se podrán dar de alta nuevas mascotas,
editar o eliminar mascotas ya registradas.
Carts administration: Acceso a la lista de
carritos de la compra tanto activos como
pendientes o finalizados. En dicha lista se
podrán modificar los carritos o eliminarlos.
Users administration: Acceso a la lista de
usuarios dados de alta en la página, donde
además se podrán dar de alta nuevos usuarios,
editar o eliminar usuarios ya registrados.
Search: Acceso a la búsqueda de mascotas.
Log out: Salir de la sesión.
o USUARIO NO REGISTRADO
Pets: Acceso a la lista de mascotas en venta,
donde se podrán comprar dichas mascotas previo
registro/autenticación en el portal.
Search: Acceso a la búsqueda de mascotas.
Register: Acceso a la página de registro de
usuarios.
Log in: Acceso a la página de autenticación de
usuarios ya registrados.
Gabriel Bermúdez Merino 24
25. Programación de una tienda virtual en Grails 3. Análisis
o USUARIO REGISTRADO
Pets: Acceso a la lista de mascotas en venta,
donde se podrán comprar dichas mascotas
siguiendo unos pasos bien definidos.
Profile: Acceso al perfil del usuario actual
donde el usuario podrá modificar su información
o eliminarse de la base de datos de la página.
Cart: Acceso al carrito de compra activo, donde
el usuario podrá eliminar las mascotas añadidas
si no satisfacen sus necesidades, así como
comprar dicho carrito.
Search: Acceso a la búsqueda de mascotas.
Log out: Salir de la sesión.
• CONTACT NAVIGATION BLOCK
En este bloque de navegación, se proporcionarán diferentes
“atajos” a diferentes servicios del portal que se
mantendrán estáticos para todos los usuarios. Los
servicios a los que se proporcionan acceso son:
o Contact: Proporciona una dirección de contacto física
con la tienda, así como un plug-in de Google Maps con
la situación de la tienda.
o Information: Proporciona información sobre el portal.
3.3.3 Render
Sección dinámica de nuestro portal donde se visualizarán las
diferentes páginas de servicios de nuestra aplicación Web. Según
el usuario que haya activo se podrá visualizar un tipo de
servicios u otros, ya que un usuario externo no podrá visualizar
el mismo contenido que el administrador, por lo que se
restringirán los accesos a dichos servicios mediante una
instrucción propia de Grails insertada en cada uno de los archivos
de controladores de las diferentes clases de dominio.
//Closure para controlar los accesos de los usuarios
def beforeInterceptor = [action:this.&auth, except:['login', 'logout', 'show', 'create',
'update', 'delete', 'save']]
3.4 Requisitos no funcionales
• FACILIDAD DE USO
Los accesos a los diferentes servicios del portal son
sencillos e intuitivos.
Gabriel Bermúdez Merino 25
26. Programación de una tienda virtual en Grails 3. Análisis
• RENDIMIENTO
El rendimiento de una aplicación Web depende en gran
medida de la capacidad de la red del usuario, pero
intentaremos disminuir la carga reduciendo el peso de los
atributos a cargar de la aplicación Web.
• INTERFICIE
La interficie debe ser lo más amigable e intuitiva
posible.
3.5 Identificación de actores y objetivos
En la aplicación habrá tres actores diferentes, por lo que cada
uno tendrá unos objetivos diferentes, pero también comparten una
serie de objetivos afines, dichos objetivos serán compartidos no
por todos los tipos de actores, sino por los más relevantes: el
Administrador y el Usuario Registrado.
• OBJETIVOS ADMINISTRADOR
o Alta de mascotas.
o Alta de carritos.
o Edición de mascotas.
o Eliminación de mascotas.
o Acceso a la lista de usuarios.
o Acceso a la lista de carritos de la compra.
• OBJETIVOS USUARIO REGISTRADO
o Compra de mascotas.
o Compra y finalización de carritos.
o Eliminar mascotas del carrito.
o Modificar el método de pago
• OBJETIVOS USUARIO NO REGISTRADO
o Log in
• OBJETIVOS AFINES
o Acceso a la lista de mascotas a la venta.
o Acceso a la ficha de la mascota.
o Acceso a la ficha del carrito de la compra.
o Acceso a la ficha del usuario.
o Alta de usuarios.
o Edición de carritos.
o Edición de usuarios.
o Eliminación de carritos.
o Eliminación de usuarios.
o Búsqueda
o Log out
Gabriel Bermúdez Merino 26
27. Programación de una tienda virtual en Grails 4. Diseño
4. Diseño
4.1 Casos de uso
4.1.1 Objetivos afines
Acceso a la lista de mascotas a la venta
Actor principal: Cualquier Usuario
Personal involucrado e intereses:
Usuario: se quiere visualizar el contenido de la lista de
mascotas a la venta.
Escenario principal de éxito:
1. El usuario quiere visualizar la lista de mascotas a la
venta desde cualquier página.
2. El usuario clica en el botón de Pets/Pets Administration
3. Se carga la vista con la lista de mascotas a la venta.
Extensiones:
3a. Si el usuario está autenticado, se carga la vista con
la lista de mascotas a la venta junto con una visualización
del carrito de la compra.
Acceso a la ficha de la macota
Actor principal: Usuario Registrado y Administrador
Personal involucrado e intereses:
Usuario Registrado y Administrador: se quiere visualizar la
ficha de una mascota en concreto.
Escenario principal de éxito:
1. El usuario quiere visualizar la ficha de una mascota en
concreto desde la página de mascotas a la venta.
2. El usuario clica sobre el identificador de la mascota.
3. Se carga la vista con la ficha de la mascota
correspondiente.
Extensiones:
1a. El usuario quiere visualizar la ficha de una mascota en
concreto desde el carrito de la compra.
2a. El usuario clica sobre el nombre de la mascota.
Acceso a la ficha del carrito de la compra
Actor principal: Usuario Registrado y Administrador
Personal involucrado e intereses:
Usuario Registrado y Administrador: se quiere visualizar la
ficha de un carrito de la compra en concreto.
Escenario principal de éxito:
Gabriel Bermúdez Merino 27
28. Programación de una tienda virtual en Grails 4. Diseño
1. El usuario quiere visualizar la ficha de un carrito de
la compra desde cualquier página.
2. El usuario clica en el botón de Cart/Carts
Administration
3. (Usuario) Se carga la vista con el carrito de la compra
activo para ese usuario.
Extensiones:
3a. (Administrador) Se carga la vista de la lista de
carritos de la compra.
1. (Administrador) El usuario clica sobre el
identificador del carrito.
2. (Administrador) Se carga la vista con el carrito
de la compra activo para ese usuario.
Acceso a la ficha del usuario
Actor principal: Usuario Registrado y Administrador
Personal involucrado e intereses:
Usuario Registrado y Administrador: se quiere visualizar la
ficha de un usuario en concreto.
Escenario principal de éxito:
1. El usuario quiere visualizar la ficha del usuario desde
cualquier página.
2. El usuario clica en el botón de Profile/Users
Administration
3. (Usuario) Se carga la vista con la ficha del usuario
actual.
Extensiones:
3a. (Administrador) Se carga la vista de la lista de
usuarios.
1. (Administrador) El usuario clica sobre el
identificador del usuario.
2. (Administrador) Se carga la vista con la ficha del
usuario.
Edición de carritos
Actor principal: Usuario Registrado y Administrador
Personal involucrado e intereses:
Usuario Registrado y Administrador: se quiere editar la
información de un carrito de la compra.
Escenario principal de éxito:
1. El usuario modificará algún campo perteneciente al
carrito de la compra.
2. El usuario clica en el botón de Cart/Carts
Administration
3. (Usuario) Se carga la vista con la ficha carrito actual.
4. El usuario clica sobre el botón Edit.
Gabriel Bermúdez Merino 28
29. Programación de una tienda virtual en Grails 4. Diseño
5. El usuario modifica los atributos que desee y salva los
datos mediante el botón Save.
Extensiones:
3a. (Administrador) Se carga la vista de la lista de
carritos.
1. (Administrador) El usuario clica sobre el
identificador del carrito.
2. (Administrador) Se carga la vista con la ficha del
carrito.
3. (Administrador) Se continúa con el punto 4.
Alta de usuarios
Actor principal: Usuario No Registrado y Administrador
Personal involucrado e intereses:
Usuario No Registrado y Administrador: se quiere dar de
alta un nuevo usuario.
Escenario principal de éxito:
1. El usuario dará de alta un nuevo usuario.
2. El usuario clica en el botón de Register/Users
Administration
3. (Usuario) Se carga la vista con la ficha de registro.
4. El usuario rellena los campos necesarios y salva los
datos mediante el botón Save.
Extensiones:
3a. (Administrador) Se carga la vista de la lista de
usuarios.
1. (Administrador) El usuario clica sobre el botón
Create.
2. (Administrador) Se carga la vista con la ficha de
registro.
3. (Administrador) Se continúa con el punto 4.
Edición de usuarios
Actor principal: Usuario Registrado y Administrador
Personal involucrado e intereses:
Usuario Registrado y Administrador: se quiere editar la
información de un usuario.
Escenario principal de éxito:
1. El usuario modificará algún campo perteneciente al
usuario.
2. El usuario clica en el botón de Profile/Users
Administration
3. (Usuario) Se carga la vista con la ficha del usuario
actual.
4. El usuario clica sobre el botón Edit.
Gabriel Bermúdez Merino 29
30. Programación de una tienda virtual en Grails 4. Diseño
5. El usuario modifica los atributos que desee y salva los
datos mediante el botón Save.
Extensiones:
3a. (Administrador) Se carga la vista de la lista de
usuarios.
1. (Administrador) El usuario clica sobre el
identificador del usuario.
2. (Administrador) Se carga la vista con la ficha del
usuario.
3. (Administrador) Se continúa con el punto 4.
Eliminación de carritos
Actor principal: Usuario Registrado y Administrador
Personal involucrado e intereses:
Usuario Registrado y Administrador: se quiere eliminar un
carrito de la compra.
Escenario principal de éxito:
1. El usuario eliminará algún carrito de la compra.
2. El usuario clica en el botón de Cart/Carts
Administration
3. (Usuario) Se carga la vista con la ficha carrito actual.
4. El usuario clica sobre el botón Delete y confirma la
eliminación.
Extensiones:
2a. (Usuario) El usuario clica en el botón Profile.
1. (Usuario) Clica en el identificador de carrito que
quiere eliminar.
2. (Usuario) Se carga la vista con la ficha del
carrito a eliminar.
3. (Usuario) Se continúa con el punto 4.
3a. (Administrador) Se carga la vista de la lista de
carritos.
1. (Administrador) El usuario clica sobre el
identificador del carrito.
2. (Administrador) Se carga la vista con la ficha del
carrito a eliminar.
3. (Administrador) Se continúa con el punto 4.
Eliminación de usuarios
Actor principal: Usuario Registrado y Administrador
Personal involucrado e intereses:
Usuario Registrado y Administrador: se quiere eliminar un
usuario.
Escenario principal de éxito:
1. El usuario eliminará algún usuario.
Gabriel Bermúdez Merino 30
31. Programación de una tienda virtual en Grails 4. Diseño
2. El usuario clica en el botón de Profile/Users
Administration
3. (Usuario) Se carga la vista con la ficha del usuario
actual.
4. El usuario clica sobre el botón Delete y confirma la
eliminación.
Extensiones:
3a. (Administrador) Se carga la vista de la lista de
usuarios.
1. (Administrador) El usuario clica sobre el
identificador del usuario.
2. (Administrador) Se carga la vista con la ficha del
usuario a eliminar.
3. (Administrador) Se continúa con el punto 4.
Búsqueda
Actor principal: Cualquier Usuario
Personal involucrado e intereses:
Usuario: se quiere realizar una búsqueda de alguna mascota.
Escenario principal de éxito:
1. El usuario eliminará realizará una búsqueda de alguna
mascota.
2. El usuario clica en el botón de Search
3. Se carga la vista con la ficha de búsqueda.
4. El usuario rellena los campos necesarios para realizar
la búsqueda.
5. Se carga la vista con los resultados de la búsqueda.
Log out
Actor principal: Usuario Registrado y Administrador
Personal involucrado e intereses:
Usuario Registrado y Administrador: se quiere cerrar la
sesión actual.
Escenario principal de éxito:
1. El usuario cerrará la sesión actual.
2. El usuario clica en el botón de Log out
3. Se cierra la sesión y se carga la vista de la página de
inicio.
4.1.2 Objetivos Administrador
Alta de mascotas
Actor principal: Administrador
Personal involucrado e intereses:
Gabriel Bermúdez Merino 31
32. Programación de una tienda virtual en Grails 4. Diseño
Administrador: se quiere dar de alta una nueva mascota en
el sistema.
Escenario principal de éxito:
1. El usuario quiere dar de alta una nueva mascota en el
sistema.
2. El usuario clica en el botón de Pets Administration
3. Se carga la vista de la lista de mascotas.
4. El usuario clica el botón Create.
5. Se carga la vista con la plantilla de mascotas.
6. El usuario rellena los campos necesarios y guarda los
cambios con el botón Save.
Alta de carritos de la compra
Actor principal: Administrador
Personal involucrado e intereses:
Administrador: se quiere dar de alta un nuevo carrito en el
sistema.
Escenario principal de éxito:
1. El usuario quiere dar de alta un nuevo carrito en el
sistema.
2. El usuario clica en el botón de Carts Administration
3. Se carga la vista de la lista de carritos.
4. El usuario clica el botón Create.
5. Se carga la vista con la plantilla de carritos.
6. El usuario rellena los campos necesarios y guarda los
cambios con el botón Save.
Edición de mascotas
Actor principal: Administrador
Personal involucrado e intereses:
Administrador: se quiere editar la ficha de una mascota en
concreto.
Escenario principal de éxito:
1. El usuario quiere editar la ficha de una mascota en
concreto.
2. El usuario clica en el botón de Pets Administration
3. Se carga la vista de la lista de mascotas.
4. El usuario clica sobre el identificador de la mascota.
5. (Administrador) Se carga la vista con la ficha de la
mascota.
6. El usuario clica sobre el botón Edit.
7. El usuario modifica los atributos que desee y salva los
datos mediante el botón Save.
Gabriel Bermúdez Merino 32
33. Programación de una tienda virtual en Grails 4. Diseño
Eliminación de mascotas
Actor principal: Administrador
Personal involucrado e intereses:
Administrador: se quiere eliminar una mascota.
Escenario principal de éxito:
1. El usuario eliminará alguna mascota.
2. El usuario clica en el botón de Pets Administration
3. Se carga la vista de la lista de mascotas.
4. El usuario clica sobre el identificador de la mascota.
5. Se carga la vista con la ficha de la mascota a eliminar.
6. El usuario clica sobre el botón Delete y confirma la
eliminación.
Acceso a la lista de usuarios
Actor principal: Administrador
Personal involucrado e intereses:
Administrador: se quiere acceder a la lista de usuarios.
Escenario principal de éxito:
1. El usuario accederá a la lista de usuarios.
2. El usuario clica en el botón de Users Administration
3. Se carga la vista de la lista de usuarios.
Acceso a la lista de carritos de la compra
Actor principal: Administrador
Personal involucrado e intereses:
Administrador: se quiere acceder a la lista de carritos de
la compra.
Escenario principal de éxito:
1. El usuario accederá a la lista de carritos de la compra.
2. El usuario clica en el botón de Carts Administration
3. Se carga la vista de la lista de carritos de la compra.
4.1.3 Objetivos Usuario Registrado
Compra de mascotas
Actor principal: Usuario Registrado
Personal involucrado e intereses:
Usuario Registrado: se quiere realizar la compra de una
mascota.
Gabriel Bermúdez Merino 33
34. Programación de una tienda virtual en Grails 4. Diseño
Escenario principal de éxito:
1. El usuario quiere realizar la compra de una mascota.
2. El usuario clica en el botón de Pets.
3. Se carga la vista de la lista de mascotas a la venta.
4. El usuario clica el botón Buy it!.
5. Se carga la vista con el carrito actual y la mascota
añadida.
Compra y finalización de carritos
Actor principal: Usuario Registrado
Personal involucrado e intereses:
Usuario Registrado: se quiere realizar la compra y
finalización de un carrito.
Escenario principal de éxito:
1. El usuario quiere realizar la compra y finalización de
un carrito.
2. El usuario clica en el botón de Cart.
3. Se carga la vista con el carrito actual.
4. El usuario clica el botón Buy Cart.
5. Se carga la vista con la factura de la compra.
Extensiones:
6a. El usuario clica el botón Edit para modificar el método
de pago.
1. El usuario modifica el método de pago.
2. El usuario salva los datos con el botón Save.
3. Se continúa con el punto 5.
Eliminar mascotas del carrito
Actor principal: Usuario Registrado
Personal involucrado e intereses:
Usuario Registrado: se quiere eliminar una mascota añadida
del carrito de la compra.
Escenario principal de éxito:
1. El usuario quiere eliminar una mascota añadida del
carrito de la compra.
2. El usuario clica en el botón de Cart.
3. Se carga la vista con el carrito actual.
4. El usuario clica el botón de eliminación que hay al lado
de cada mascota añadida.
5. Se vuelve al paso 3.
Modificar el método de pago
Actor principal: Usuario Registrado
Personal involucrado e intereses:
Gabriel Bermúdez Merino 34
35. Programación de una tienda virtual en Grails 4. Diseño
Usuario Registrado: se quiere modificar el método de pago.
Escenario principal de éxito:
1. El usuario quiere modificar el método de pago.
2. El usuario clica en el botón de Cart.
3. Se carga la vista con el carrito actual.
4. El usuario clica el botón Edit para modificar el método
de pago.
5. El usuario modifica el método de pago.
6. El usuario salva los datos con el botón Save.
4.1.4 Objetivos Usuario No Registrado
Log in
Actor principal: Usuario No Registrado
Personal involucrado e intereses:
Usuario No Registrado: se quiere iniciar una nueva sesión.
Escenario principal de éxito:
1. El usuario quiere iniciar una nueva sesión.
2. El usuario clica en el botón de Log in.
3. Se carga la vista de autenticación.
4. El usuario rellena los campos e inicia la sesión.
4.2 Diagramas
Siguiendo el modelo Vista-Controlador en que está basado Grails
el cuál simplifica el desarrollo de aplicaciones Web mediante la
reducción de archivos de configuración y generando
automáticamente la mayoría de elementos necesarios por una
aplicación Web sobre una base de datos
Gabriel Bermúdez Merino 35
36. Programación de una tienda virtual en Grails 4. Diseño
realizaremos el diseño del diagrama de clases de nuestra
aplicación. El hecho de que se trate de una aplicación Web, para
una comprensión más sencilla, proporcionaremos un diagrama de
dominio de las clases, el modelo Vista-Controlador mencionado
anteriormente y un mapa de portal el cuál nos informará sobre la
navegación dentro del portal.
4.2.1 Diagrama de dominio
El diagrama de dominio de nuestra aplicación Web, nos ayudará a
la comprensión de la configuración de la base de datos de
nuestra aplicación y nos dará una idea de la estructuración de
nuestro portal.
PET
N
USER
1
N
CART
N
Como podemos observar, tendremos 3 clases principales
relacionadas entre sí, las cuáles serán la base de la estructura
de la base de datos y de la aplicación Web.
4.2.2 Modelo Vista-Controlador
En nuestra aplicación, el Controlador recoge las peticiones
realizadas por el servidor, posteriormente genera los datos
necesarios y la vista que se mostrará en el Render del navegador
del usuario. Realizaremos tres modelos de Vista-Controlador, uno
por cada Clase de dominio.
4.2.2.1 Vista-Controlador User
El usuario realiza una acción en el
VIEW
portal, el cuál envía una petición al
controlador, el cuál genera la vista de
la respuesta a la petición del usuario.
PET
Los controladores que generan las
vistas para el usuario son los básicos
del CRUD a los cuáles añadimos los
realizados para la gestión de otras
peticiones. CONTROLLER
Gabriel Bermúdez Merino 36
37. Programación de una tienda virtual en Grails 4. Diseño
Los controladores que generan las vistas para el usuario son los
básicos del CRUD a los cuáles añadimos los realizados para la
gestión de otras peticiones.
• Login: Controlador que comprueba que el usuario
introducido y la contraseña corresponden a los almacenados
en la base de datos, y si coincide, se almacena en la
variable de sesión para la gestión de usuarios en los
demás servicios de los portales.
• Logout: Controlador que cierra la sesión del usuario
activo y redirige el portal a la página de inicio por
defecto.
4.2.2.2 Vista-Controlador Pet
El usuario realiza una petición en un
VIEW
elemento perteneciente a la clase de
dominio de las mascotas que es
gestionada por los controladores de
dicha clase de dominio generando los
USER
elementos de la vista que se
renderizará.
Los controladores que generan las
CONTROLLER
vistas para la petición del usuario en
el elemento de mascotas, son los
básicos del CRUD a los cuáles añadimos los realizados para la
gestión de otras peticiones.
• Upload_image: Controlador que gestiona el almacenamiento
de la imagen correspondiente a la mascota que se crea o
edita.
• Image_link: Controlador que crea el link con la imagen
correspondiente a la mascota actual.
• Search: Controlador que gestiona la búsqueda de mascotas
siguiendo un tipo de búsqueda establecido por el usuario.
4.2.2.3 Vista-Controlador Cart
El usuario realiza una petición en un
elemento perteneciente a la clase de VIEW
dominio del carrito que es gestionada
por los controladores de dicha clase de
dominio generando los elementos de la
vista que se renderizará. CART
Los controladores que generan las
vistas para la petición del usuario en
el elemento del carrito, son los CONTROLLER
básicos del CRUD a los cuáles añadimos
Gabriel Bermúdez Merino 37
38. Programación de una tienda virtual en Grails 4. Diseño
los realizados para la gestión de otras peticiones.
• CartBuy: Controlador que gestiona la compra de las
mascotas añadiéndolas al carrito activo.
• EndCart: Controlador que gestiona la compra del carrito
estableciendo el método de pago que utilizará el usuario.
• DelOfCart: Controlador que muestra el estado final del
carrito una vez confirmada la compra del mismo.
4.2.3 Site Maps
Los Site Maps de nuestra aplicación Web, nos proporcionan
información sobre la navegación entre las diferentes páginas
Home Page
Admin login
Pets list Search Carts List Users Logout
Delete Update Show Pet Search Result Status Update
Delete Show User Update Delete
Gabriel Bermúdez Merino 38
39. Programación de una tienda virtual en Grails 4. Diseño
Home Page
User login
Profile Pets list sale Search Cart Logout
Update Delete Buy Pet Show Pet Search Result Buy cart Update Delete
Pay Mode
Confirm
Todos los objetos mostrados en los Site Maps están representados
por controladores de las diferentes clases los cuáles se
explicarán en el apartado de Implementación.
Gabriel Bermúdez Merino 39
40. Programación de una tienda virtual en Grails 5. Implementación
5. Implementación y pruebas
5.1 Entorno de desarrollo
Así como en el apartado de análisis hemos realizado una
valoración inicial antes de implementar el código, en este
apartado realizaremos un balance de algunas herramientas
utilizadas para la implementación del proyecto.
5.1.1 GNU/Linux
El sistema operativo escogido para programar la aplicación es
GNU/Linux. Se ha escogido este sistema porque ofrece un entorno
de programación más amigable para el desarrollador además de ser
de libre distribución. Grails, como Java, ofrece una
compatibilidad con cualquier sistema operativo, lo que hace que
el sistema operativo en que se haya desarrollado no sea
relevante.
5.1.2 GEdit
El editor de texto por defecto del entorno Gnome de GNU/Linux,
que ofrece la posibilidad de inclusión de diferentes plugins que
hacen más sencillo el desarrollo de aplicaciones en cualquier
lenguaje de programación.
5.1.3 Mozilla Firefox 2.14
Firefox ha sido el navegador elegido para realizar las pruebas
de nuestra aplicación Web, aunque como con el sistema operativo,
la implementación final no establece un navegador por defecto,
por lo que el navegador Web tampoco es relevante.
5.1.4 Groovy
Como ya he comentado varias veces durante la memoria, mi
conocimiento sobre este lenguaje de programación era nulo antes
del inicio de este proyecto, por este motivo y al ser una de las
partes fundamentales del proyecto, este lenguaje de Scripting
dispone de su propio apartado en esta memoria. La compatibilidad
en los sistemas operativos es muy alta, ya que tanto Mac,
Unix/Linux como Windows son compatibles con este lenguaje
importando sus librerías.
5.1.5 Grails
Al igual que Groovy, el framework Web Grails tambien dispone de
un apartado propio en la memoria debido a su relevancia en este
proyecto. La compatibilidad en los sistemas operativos es muy
alta, ya que tanto Mac, Unix/Linux como Windows son compatibles
con este lenguaje importando sus librerías.
Gabriel Bermúdez Merino 40
41. Programación de una tienda virtual en Grails 5. Implementación
5.2 Seguimiento y problemáticas
En este apartado realizaremos un seguimiento a la implementación
de nuestra aplicación Web, durante el cuál también iremos
descubriendo las diferentes problemáticas con las que nos hemos
encontrado durante dicha implementación.
5.2.1 Estructura y persistencia
El primer paso de una implementación en Grails es establecer la
estructura de nuestro proyecto, para ello, Grails, aporta un
comando especial que nos asiste en la construcción de la
estructura de nuestro proyecto.
Creamos una carpeta en cualquier directorio de nuestro sistema
operativo, e introducimos el siguiente comando de Grails:
$> grails create-app projectName
con este comando creamos la estructura de nuestro proyecto que
quedará dividido en diferentes carpetas distribuidas según la
funcionalidad que tienen dentro del proyecto.
Una vez ya hemos establecido la estructura del proyecto
configuramos la persistencia de datos mediante la creación de
una base de datos (en nuestro caso MySQL) y posterior
configuración en nuestro proyecto de dicha BBDD. Para ello
descargamos el driver de la BBDD que queremos utilizar para la
persistencia de datos y lo almacenamos en la carpeta …/lib.
Posteriormente configuramos el fichero …/grails-
app/conf/ApplicationDataSource.groovy en el cuál estructuramos
el fichero según las diferentes BBDD que se utilizaran para los
diferentes estados de creación de la aplicación Web.
dataSource {
pooled = false
driverClassName = "com.mysql.jdbc.Driver"
username = "root"
password = ""
}
…
environments {
development {
dataSource {
dbCreate = "update" // one of 'create', 'create-
drop','update'
url = "jdbc:mysql://localhost/petStore_dev"
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:mysql://localhost/petStore_test"
}
}
production {
dataSource {
dbCreate = "update"
url =
"jdbc:mysql://localhost/petStore_prod;shutdown=true"
}
}
}
Gabriel Bermúdez Merino 41
42. Programación de una tienda virtual en Grails 5. Implementación
Como podemos observar configuramos el fichero con el driver que
hemos descargado, con su usuario y password, además del path de
cada BBDD que vamos a utilizar durante el desarrollo del
proyecto.
A continuación creamos las clases de dominio más relevantes de
nuestro proyecto utilizando un comando de Grails, las cuales
posteriormente también se utilizará su estructura en la BBDD.
Para la creación de estas clases seguiremos el diagrama de
dominio del apartado de diseño.
PET
N
USER
1
N
CART
N
Creamos la clase de dominio mediante el comando de Grails y
posteriormente rellenamos las clases con los atributos, las
constraints y las relaciones entre las clases.
$> grails create-domain-class pet
import grails.util.GrailsUtil
import org.springframework.web.multipart.MultipartFile
import org.codehaus.groovy.grails.commons.ConfigurationHolder
class Pet {
String name
String type
String description
Float price
byte[] image
static hasMany = [carts:Cart]
static belongsTo = Cart
static constraints = {
name(maxLength:50, blank:false)
type(inList:['Bird','Cat', 'Dog', 'Fish', 'Ferret',
'Rodent'], blank:false)
description()
price(min:0f)
image(nullable:true, maxSize:65536) /* 64K */
}
static mapping = {
description type: 'text'
}
}
Gabriel Bermúdez Merino 42
43. Programación de una tienda virtual en Grails 5. Implementación
$> grails create-domain-class cart
class Cart {
String status
String payment
String numberTarget
Float total
Map contentBuy=[1 : 1]
static hasMany = [pets:Pet]
static belongsTo = [user:User]
static constraints = {
payment(inList:['Card','Against reimbursement'])
status(inList:['In process', 'Pending', 'Completed'])
total(min:0f)
}
}
$> grails create-domain-class user
class User {
String name
String firstName
String lastName
String NIF
String postalAddress
String emailAddress
String userId
String password
static hasMany = [carts:Cart]
static constraints = {
userId(length:5..8, unique:true)
password(length:6..8)
name(blank:false)
firstName(blank:false)
lastName(blank:false)
NIF(length:9,unique:true)
postalAddress(maxLength:255,blank:true)
emailAddress(maxLength:50,blank:false,email:true)
}
}
Para finalizar este punto, establecemos la estructura de la BBDD
mediante otro comando de Grails, el cuál inicia la aplicación
Web a la vez que crea la estructura de la aplicación en la BBDD.
$> grails run-app
Gabriel Bermúdez Merino 43
44. Programación de una tienda virtual en Grails 5. Implementación
5.2.2 Controladores y vistas
Una vez configurada la estructura de la aplicación, sus clases
de dominio y la Base de Datos, necesitamos configurar los
controladores de las clases y sus respectivas vistas mediante
comandos de Grails y la posterior personalización editando los
ficheros que se crearán.
$> grails generate-all className
Mediante este comando de Grails se generan los controladores y
las vistas básicos para realizar tareas CRUD. Posteriormente los
editaremos para añadir funcionalidades a los controladores y
crearemos sus respectivas vistas.
A continuación veremos las funcionalidades añadidas a los
controladores y las ventajas que ha supuesto su implementación
en Groovy y el uso de gsp’s para las vistas.
5.2.2.1 Controladores
Base Controller
Base Controller es un pequeño controlador del cuál extienden
todos los Controladores que proporciona un chequeo continuo de
los accesos a los controladote, comprobando que el usuario esta
autentificado y compara los permisos con de acceso con los
establecidos en cada controlador.
abstract class BaseController{
def auth(){
if(!session.userId){
redirect(controller:'user', action:'login')
return false
}
}
}
Pets
Como veremos a continuación, en el controlador de mascotas (Pet)
añadiremos las funciones de Cargar imágenes y Búsqueda, además
de los permisos de acceso a los controladores y la variable de
Scaffolding. Cargar imágenes nos proporciona la posibilidad de
subir imágenes para añadirlas al perfil de las mascotas y
Búsqueda nos proporciona el servicio de realizar búsquedas entre
la lista de mascotas a la venta.
Permisos de acceso y Scaffolding
…
def scaffold = Pet
//Closure para controlar los accesos de los usuarios
def beforeInterceptor = [action:this.&auth, except:['show', 'list']]
…
Gabriel Bermúdez Merino 44
45. Programación de una tienda virtual en Grails 5. Implementación
Como podemos observar, la restricción es para cualquier
acción excepto para show y list.
Cargar imágenes
…
def upload_image = {
def pet = Pet.current(session)
// Obtenemos el fichero de la imagen del request multi-parte
def f = request.getFile('image')
// Listado de las extensiones permitidas
def okcontents = ['image/png', 'image/jpeg', 'image/gif']
if(! okcontents.contains(f.getContentType())){
flash.message = "La imagen debe tener la extensión:
${okcontents}"
render(view:'create', model:[pet:pet])
return;
}
// Guardamos la imagen y su extension
pet.image = f.getBytes()
log.info("Imagen subida")
// Validamos el trabajo, comprobamos que la imagen no sea muy grande
if(!pet.save()){
render(view:'create', model:[pet:pet])
return;
}
flash.message = "Imagen subida correctamente."
// redirect(action:'show')
}
def image_link = {
def imagePet = Pet.get(params.id)
if(!imagePet || !imagePet.image){
response.sendError(404)
return;
}
OutputStream out = response.getOutputStream();
out.write(imagePet.image);
out.close();
}
…
Como podemos observar, la problemática más grande que ha
tenido este servicio del controlador ha sido la
configuración de los contenidos aceptados y el almacenaje de
la imagen subida mediante la distribución de las referencias
entre la base de datos y el objeto subido.
Búsqueda
…
def search = {
if(request.method == 'POST'){
def auxName = params.name
def auxType = params.type
params.name = null
params.type = null
PetQuery query = new PetQuery()
bindData(query, params)
/*if(auxName != null){
if(auxType != null){
render(view:'list',
model:[petList:Pet.findAllByNameLikeAndTypeLike('%' + auxName + '%',
'%' + auxType + '%')])
Gabriel Bermúdez Merino 45
46. Programación de una tienda virtual en Grails 5. Implementación
}else{
render(view:'list', model:[petList:
Pet.findAllByNameLike('%' +
auxName + '%')])
}
}else{
render(view:'list', model:[petList:
Pet.findAllByTypeLike('%' + params.type + '%')])
}*/
def criteria = Pet.createCriteria()
def results = criteria {
and {
like('name', '%' + auxName + '%')
like('type', '%' + auxType + '%')
if(query.price) {
switch (query.priceOperator) {
case PetQuery.PriceOperator.AT_LEAST:
ge('price', query.price)
break
case PetQuery.PriceOperator.EXACTLY:
eq('price', query.price)
break
case PetQuery.PriceOperator.AT_MOST:
le('price', query.price)
break
default:
log.error "Found unexpected
value for price" + "operator - ${query.priceOperator}"
}
}
}
}
render(view:'list', model:[raceList:results])
}
}
…
Para la implementación de este controlador, se han
realizado dos pasos previos:
• Creación de una clase Java llamada PetQuery, que
únicamente está formada por la definición de los
atributos que se van a utilizar en las consultas y
sus respectivos métodos getter y setter.
• Uso de una clase propia de Grails, criteria, que nos
proporciona un sistema de búsqueda más sencillo y
eficaz.
Una vez realizados estos dos pasos previos, se han
configurado las llamadas a dicha clase Java y a criteria,
y los parámetros de búsqueda que se quieran utilizar
mediante diferentes condicionales, y finalmente retornando
el resultado de dicha búsqueda.
Cart
Como veremos a continuación, en el controlador de carritos
(Cart) añadiremos las funciones de Compras del carrito,
Eliminación del carrito y Finalización del carrito, además de
los permisos de acceso a los controladores y la variable de
Scaffolding. Compras del carrito nos proporciona una vista del
contenido del carrito así como la posibilidad de añadir o
Gabriel Bermúdez Merino 46
47. Programación de una tienda virtual en Grails 5. Implementación
eliminar mascotas a dicho carrito, Eliminación del carrito nos
proporciona la posibilidad de eliminar mascotas añadidas al
carrito y Finalización de carrito, como su propio nombre indica,
nos da la posibilidad de finalizar la compra proporcionándonos
una “factura electrónica” del pedido.
Permisos de acceso y Scaffolding
…
def scaffold = Cart
//Closure para controlar los accesos de los usuarios
def beforeInterceptor = [action:this.&auth]
…
Como podemos observar, la restricción es para cualquier
acción.
Compras del carrito
…
def cartBuy = {
def user = User.findByUserId(session.userId);
params.petId = params.id
def cart = null;
def value = null
if(user.name == 'default'){
redirect(controller:'user', action:'login')
}
def findCart = {
if(it.status ==~ 'In process'){
cart = it
}
}
user.carts.each(findCart);
if(cart == null){
//redirect(action:create)
params.status='In process'
params.payment='Against reimbursement'
params.numberTarget=''
params.total=0.0
params.user=user
save()
if(params.petId == null) redirect(controller:'pet',
action:'listPetsSale')
}
if(params.id != null){
def pet = Pet.findById(params.petId)
if(pet != null){
if(cart.contentBuy.containsKey(pet.id)){
value = cart.contentBuy.get(pet.id)
cart.contentBuy.put(pet.id, value+1)
}else{
cart.pets.add(pet)
cart.contentBuy.put(pet.id, 1)
}
cart.total += pet.price
}
}
params.petId = null
return [ 'cart' : cart ]
}
…
Gabriel Bermúdez Merino 47
48. Programación de una tienda virtual en Grails 5. Implementación
Como podemos observar, este servicio nos proporciona tanto
la compra de mascotas como la visión del contenido del
carrito. Si el usuario compra una mascota o quiere ver el
contenido de su carrito y no tiene ninguno activo se le crea
automáticamente uno. Si el usuario solo quiere ver el
contenido del carrito se le carga la vista apropiada, sino
el sistema busca el animal que se desea comprar y se le
añade al carrito, posteriormente carga la vista de carrito
actual. La problemática más relevante que me he encontrado a
la hora de realizar este controlador era el uso de HashMaps
para almacenar el contenido del carrito conjuntamente con la
cantidad de animales del mismo tipo añadidos, el cuál se
solvento con un tipo de declaración mixta de Java y Groovy
en la clase Cart.
Eliminación del carrito
…
def endCart ={
def user = User.findByUserId(session.userId);
def cart = null;
def findCart = {
if(!it.status ==~ 'In process'){
cart = it
}
}
user.carts.each(findCart);
cart.setStatus('Pending');
return[ 'user' : user, 'cart' : cart ]
}
…
Este servicio nos proporciona la posibilidad de eliminar
del contenido del carrito una mascota que ya no queremos
comprar, posteriormente actualiza la vista del carrito
actual.
Finalización del carrito
…
def delOfCart = {
def user = User.findByUserId(session.userId);
def pet = Pet.findById(params.id);
def value = null
def findCart = {
if(it.status ==~ 'In process'){
if(cart.contentBuy.get(pet.id)>1){
value = cart.contentBuy.get(pet.id)
cart.contentBuy.put(pet.id, value - 1)
}else{
it.contentBuy.remove(pet.id)
it.pets.remove(pet)
}
it.total = it.total - pet.price
redirect(action:cartBuy)
}
}
user.carts.each(findCart);
}
…
Gabriel Bermúdez Merino 48