Skip to main content

Sample Store Catalog using using Groovy and Grails

Posted by caroljmcdonald on April 28, 2008 at 7:35 PM PDT




http-equiv="content-type">
grailsexample

Sample Store Catalog using using Groovy and Grails





This Catalog Sample app demonstrates the usage of Groovy and Grails to
implement pagination of data sets for a Store Catalog.

href="https://techdayscode.dev.java.net/servlets/ProjectDocumentList?folderID=9118&expandFolder=9118&folderID=9118">
download Catalog sample code



Overview of the Technologies and Frameworks in the Sample Application



Grails aims to bring the
"coding by convention" paradigm to Groovy. It's an open-source web
application framework that leverages the Groovy language and
complements Java Web development.

Groovy is an agile and dynamic
language
for the Java Virtual Machine, it compiles
to Java bytecode, and it combines popular features from
languages such as Smalltalk, Python, and Ruby.

Grails is a
Model-View-Controller based framework that simplifies the development
of  web applications by reducing the need for configuration files
and by generating a lot of the things needed in
a database-backed Web application.


mvc.gif style="width: 304px; height: 334px;" />






The Sample Application

The sample application displays an online catalog of pets sold in a pet
store. The image below shows the Catalog Listing page, which allows a
user to
page through a list of items
in a store.



 

listpet.jpg width="353" height="532" />





The Model - Grails Domain Classes

The Model is your application's persistent business domain objects.
A Grails domain
object
instance represents a row in a database table.  The command

grails
create-domain-class Item
generates the
 style="color: rgb(0, 0, 153); font-weight: bold;">Item.groovy

class shown below corresponding to the item table.



After model code
generation you have to
add the domain object's attributes and relationships. The
 style="color: rgb(0, 0, 153); font-weight: bold;">Item

class has a many-to-one relationship
with the Address
class. In Grails
 style="color: rgb(0, 0, 153); font-weight: bold;">hasMany

is the
many end of a many-to-one  relationship.




cellspacing="0">
Code Sample from: style="font-weight: bold;">domain\Item.groovy



class Item
{

  Long id

  String name

  String description

  String imageurl

  String imagethumburl

  BigDecimal price

  Address
            address

}

   


           

           
 
cellspacing="0">
Code Sample from: style="font-weight: bold;">domain\Address.groovy



class Address
{

  Long id

  String street1

  String street2

  String city

  String state

  String zip

  float latitude

  float longitude

  static
hasMany = [item:Item]


}

   


           

           



classrel.gif src="http://weblogs.java.net/blog/caroljmcdonald/archive/classrel.gif"
height="134" width="274">



SQL  Sample for items table style="font-family: monospace;">



CREATE TABLE item (

 id BIGINT NOT NULL,

 product_id BIGINT NOT NULL,

 name VARCHAR(30) NOT NULL,

 description VARCHAR(500) NOT NULL,

 imageurl VARCHAR(55),

 imagethumburl VARCHAR(55),

 price DECIMAL(14,2) NOT NULL,

 address_id BIGINT NOT NULL,

 primary key (id),

 foreign key (address_id) references address(id),

 foreign key (product_id) references product(id)

);

   


     



Groovy with Grails dynamically generates getters and setters and the
dynamic
methods Item.save(), Item.delete(),  Item.list(), Item.get() to
retrieve/update data from/to
the db table.



Grails Object Relational Mapping (GORM) is currently built on top of
Hibernate but you don't have to know Hibernate to use it
( Grails  1.1 will
support  the Java Persistence API
) .





The Controller



Controllers handle incoming http requests, interact with the model to
get data and to process requests,  invoke the correct view, and
direct domain data to the view for display. 
In Grails, http requests are handled by Controller classes which
are made up
of one or more action methods that are executed on request and then
either render
a Groovy Server Page or redirect to another
action. Grails routes requests to the controller action which
corresponds to the URL mapping for the request. In Grails the default
mapping from URL to action method follows this convention: http://host/ style="font-weight: bold;">app/controller/action/id .  For
example the URL http://host/catalog/item/list
calls the
list style="font-family: monospace; font-weight: bold;"> style="color: rgb(0, 0, 153);"> style="font-weight: bold;">action method in the style="font-weight: bold;"> item controller style="font-family: monospace;"> style="color: rgb(0, 0, 153); font-weight: bold;">class
shown below.     href="http://grails.codehaus.org/Scaffolding">Grails
Scaffolding provides a series of standardized
Controller action methods for listing, showing, creating, updating, and
deleting
objects of a class.  These standardized actions
come with both controller logic and default view Groovy Server Pages.
The command generate-all
Item
generates the Item controller and the List, Show, Create, Edit
Groovy Server Pages for the Item domain object. The style="font-family: monospace;"> style="color: rgb(0, 0, 153); font-weight: bold;">ItemController
style="color: rgb(0, 0, 153); font-weight: bold;">list
action renders a view with a paginated list of item objects.


Code Sample from: grails-app\ style="font-weight: bold;">controllers\ItemController.groovy


class ItemController
{



 
def index = {
redirect(action:list,params:params) }
style="font-family: monospace;">



  def list = {

    if(!params.max) params.max = 10

    [ itemList: Item.list( params ) ]

  }

. . .

 

     



When a URL has a controller but no action (e.g.
http://localhost:8080/catalog/item/  ), Grails defaults to the
index action. In the style="font-weight: bold;"> style="font-family: monospace;"> style="color: rgb(0, 0, 153); font-weight: bold;">ItemController
code the  style="color: rgb(0, 0, 153); font-weight: bold;"> style="font-family: monospace;"> style="color: rgb(0, 0, 153); font-weight: bold;">index
action method redirects to the style="color: rgb(0, 0, 153); font-weight: bold;">list
action.  The style="color: rgb(0, 0, 153); font-weight: bold;">ItemController
style="color: rgb(0, 0, 153); font-weight: bold;">list action
method calls the style="color: rgb(0, 0, 153); font-weight: bold;">Item.list() method
which returns an ArrayList of item objects retrieved from the item
database table . If there are more than style="font-family: monospace;">params.max objects in the
table, Grails creates next and previous pagination links automatically.
The itemList style="font-family: monospace;"> variable  is
automatically made available to the view by the framework.



After executing
code, actions usually render a GSP in the views directory
corresponding to the name of the controller and action, for example the
list action will render the grails-app\views\item\list.gsp .


The View

The view layer generates a web
page, using data from domain objects provided by the controller. In
Grails, the view is rendered using href="http://docs.codehaus.org/display/GRAILS/Developer+-+Groovy+Server+Pages">Groovy
Server Pages. Below is part of the list.gsp for the Catalog
application (note I modified the html table format from the default
generated).




Code Sample from: grails-app\ style="font-weight: bold;">views\item\list.gsp





  

    

        style="color: rgb(0, 0, 153); font-weight: bold;">
property="name" title="Name" />

        property="imagethumburl" title="Photo" />

        property="price" title="Price" />

    


  

  

     style="color: rgb(0, 0, 153); font-weight: bold;">
in="${itemList}"
status="i"
var="item">

       


          

          

          


       

    

 

 


            
     
action="show" id="${item.id}">

               
${item.name?.encodeAsHTML()}

          


            
createLinkTo(dir:'images',file: style="color: rgb(0, 0, 153); font-weight: bold;">item.imagethumburl)}"/>

          
${item.price?.encodeAsHTML()}


     



 
total="${Item.count()}" />



     

     



The view uses instance variables set by the controller to
access the data it needs to render the GSP.



GSP has a GroovyTagLib similar to the  JSP tag library. are
GroovyTags.



  




       The href="http://grails.codehaus.org/GSP+Tag+-+sortableColumn">sortableColumn
tag renders a sortable column to support sorting in tables.



in="${itemList}" status="i"
var="item">

loops through each object in the itemList style="font-family: monospace;"> variable,
which is an ordered style="font-weight: bold;">ArrayList of
 style="color: rgb(0, 0, 153); font-weight: bold;">Item 
model
objects,  and assigns each
 style="color: rgb(0, 0, 153); font-weight: bold;">Item

model object to the
 style="color: rgb(0, 0, 153); font-weight: bold;">item 
variable.

 
action="show"
id="${item.id}">${item.name?.encodeAsHTML()}
 
 href="http://grails.org/doc/1.0.x/ref/Tags/link.html">the
GroovyTag creates an html anchor tag href
based on the action, id, controller
parameters specified. In this example it generates a link to the
item/show/id action which when clicked will display the
corresponding item details. For
example this line will generate the following HTML for the variable item:
<a class="attribute-name"> href="/catalog/item/show/2">Friendly Cat class="end-tag">a>

src="${createLinkTo(dir:'images',file:item.imagethumburl)}"/>
style="color: rgb(0, 0, 153); font-weight: bold;"> 

The href="http://docs.codehaus.org/display/GRAILS/Tag+-+createLinkTo">createLinkTo
tag generates an HTML link for the
item's
imagethumburl
 style="color: rgb(0, 0, 153); font-weight: bold;">
attribute. 



${item.price?.encodeAsHTML()}

displays the value of the 
 style="color: rgb(0, 0, 153); font-weight: bold;">item 's price 
attribute
as
escaped HTML text.


total="${Item.count()}" />
The href="http://grails.codehaus.org/GSP+Tag+-+paginate">paginate tag
creates next/previous buttons and a breadcrumb trail to allow
pagination of results using the Item.count()
domain method.


The Show Action Method

In Grails the mapping for the URL http://host class="attribute-value">/item/show/1  (
http://host/controller/action/id
)  will
route to the style="color: rgb(0, 0, 153); font-weight: bold;">show
action in the style="color: rgb(0, 0, 153); font-weight: bold;">ItemController
passing 1 to the method as the style="color: rgb(0, 0, 153); font-weight: bold;">id of
the style="color: rgb(0, 0, 153); font-weight: bold;">params parameter
hash. The style="color: rgb(0, 0, 153); font-weight: bold;">show
action of the style="color: rgb(0, 0, 153); font-weight: bold;">ItemController class
is shown below. The style="color: rgb(0, 0, 153); font-weight: bold;">ItemController
style="color: rgb(0, 0, 153); font-weight: bold;">show
action renders a view showing the details of the item object
corresponding to the id parameter.


Code Sample from: grails-app\controllers\ItemController.groovy


 def show = {

   def item = style="color: rgb(0, 0, 153); font-weight: bold;">Item.get
( style="color: rgb(0, 0, 153); font-weight: bold;">params.id )



   if(!item) {

      flash.message = "Item not found with id
${params.id}"

      redirect(action:list)

   }

   else { return [ item : item ] }

 }



 

     



The style="color: rgb(0, 0, 153); font-weight: bold;">show
action method  calls the style="color: rgb(0, 0, 153); font-weight: bold;">Item.get()
style="color: rgb(0, 0, 153); font-weight: bold;">

 style="font-family: monospace;"> style="color: rgb(0, 0, 153); font-weight: bold;">method
which queries the items table returning the style="font-family: monospace;"> style="font-family: monospace;"> style="color: rgb(0, 0, 153); font-weight: bold;">item instance
variable corresponding to the item with the attribute style="font-family: monospace;"> style="color: rgb(0, 0, 153); font-weight: bold;">id
(primary key)
equal to the  style="color: rgb(0, 0, 153); font-weight: bold;">id
parameter. This is the equivalent of the following sql : style="font-family: monospace;">select * from items where id=' style="font-family: monospace;"> style="color: rgb(0, 0, 153); font-weight: bold;">1' .
The style="color: rgb(0, 0, 153); font-weight: bold;">item variable
is automatically made available to the Show view by the framework. style="font-weight: bold;">




The Show View GSP


After executing
code in the action, the style="color: rgb(0, 0, 153); font-weight: bold;">show action
renders the app/views/item/show.gsp . Below is the GSP for
the item show view :






 
   
     
   
   
     
Code Sample from: grails-app\ style="font-weight: bold;">views\item\show.gsp


Detail of item



     





   

                                
     

                                
     

   
                   
     

   

                                   
     

                                  
     

   
                       
     

   

                                  
     

                                   
     

   
                                           
     

   

                                   
     

                                   
     

   

   

                                   
     

                                  
     

   
                       
     



class="name">Name:class="value">${item.name}
class="name">

          
Description:

       
class="value">

          
${item.description}

       
class="name">Imageurl:class="value">

           
createLinkTo(dir:'images',file: style="color: rgb(0, 0, 153); font-weight: bold;">item.imageurl)}"
/>

       
class="name">Price:class="value">$
${item.price}
class="name">Address:class="value">

         
${item?.address?.street1},
${item?.address?.city},    
     

         
${item?.address?.state}

       
  





${item.description}

displays the value of the 
 style="color: rgb(0, 0, 153); font-weight: bold;">item 's 
description
 style="color: rgb(0, 0, 153); font-weight: bold;"> 
attribute.
src="${createLinkTo(dir:'images',file:item.imageurl)}" />
 style="color: rgb(0, 0, 153); font-weight: bold;"> 
generates an HTML
image tag for the
 style="color: rgb(0, 0, 153); font-weight: bold;">item's imageurl

attribute.

${item?.address?.city}
displays the value of the 
 style="color: rgb(0, 0, 153); font-weight: bold;">item's 
 style="font-family: mon;">address city
 style="color: rgb(0, 0, 153); font-weight: bold;"> 
attribute.


The image below shows the resulting page for the url
http://host/catalog/item/show/105, which displays the item 105's
details:


    

showpet.jpg width="677" height="728" />


Layouts

Grails layouts 
let you put common html on multiple views (for
example page headers,  footers, sidebars).  Default layout
templates are in the views layouts directory with a file name
corresponding to the controller, or you can associate a view with a
layout using the "layout" meta tag to your page:

"layout" content= class="code-quote">"main">

To add a title and parrot image to the
top of the Pet Catalog pages, I put this table in the
app\views\layouts\main.gsp  layout:


Code Sample from: app/views/layouts/main.gsp




 

  

  

 

Pet Catalog

     src="${createLinkTo(dir:'images',file:'pet_logo.jpg')}"/>

  




     







Conclusion

This concludes the sample application which demonstrates how to work
with Groovy and Grails  to page through a list
of  Item Model objects
which are retrieved using Item
Controller action methods, and
displayed using Item View GSPs.




Setting Things Up and Running the Sample code on style="font-weight: bold;">MySQL and Jetty:



     
  1. If MySQL
    is already installed, then download href="https://glassfish.dev.java.net/downloads/v2ur1-b09d.html">GlassFish
    v2 UR1. Otherwise you can also Download href="http://glassfish.java.net/">GlassFish v2 UR1
    and MySQL co-bundle
    from the usual Download
    Page
    ( href="http://docs.sun.com/app/docs/doc/820-3797/ggkei?l=en&q=mysql&a=view">instructions).
       

       

     

  2.  
  3. Download and
    install Grails.

       

     

  4.  
  5. Download the href="http://techdayscode.dev.java.net/servlets/ProjectDocumentList?folderID=8159">sample
    code and extract its contents. You should now see the newly
    extracted directory as /Catalog
,
where is the directory where
you unzipped the sample package. For example, if you extracted the
contents to C:\ on a Windows machine, then your newly
created directory should be at C:\Catalog

The
file 
"/Catalog/grails-app/conf/DataSource.groovy"
is configured
for a MySQL
configuration.


  • Start the MySQL database as follows:


    • > mysqld_safe --user root
      --console



  • Create the pet-catalog database:


    • > mysqladmin
      create petcatalog --user root


      href="http://dev.mysql.com/doc/refman/5.0/en/batch-commands.html">

  • href="http://dev.mysql.com/doc/refman/5.0/en/batch-commands.html">Create
    the tables in the MySQL pet-catalog database as follows:


    • [prettify]shell> mysql pet-catalog < catalog.sql[/prettify]
    • using the file catalog.sql file from the /Catalog
      directory.


             

           

    •    

     

  •  
  • Run the project as follows:

    in a command window in the /Catalog directory enter the command

     

  •  

  •    
    > grails run-app

  • This will run the Application using the built-in Jetty Servlet engine.

    When you run the project, your browser should display the Catalog home
    page at http://localhost:8080/catalog/ .




    Run the Sample code on Glassfish:

    1. Use the  WAR file in
      /Catalog/Catalog.war
         
      or Create a WAR file:
      • [prettify]> grails war[/prettify]
    2. Copy the WAR file (catalog-0.1.war) to  your
      Glassfish installation "domains/domain/autodeploy"
      directory. (Start Glassfish and MySQL if you haven't already)


    3. Enter the URL  http://localhost:8080/catalog-0.1
      in
      your browser, you should see the home page of the Sample
      Application.

    References

    • To learn how to build a Grails CRUD app see: href="http://blogs.sun.com/arungupta/entry/totd_30_crud_application_using">TOTD
      #30: CRUD Application using Grails - Hosted on Jetty and HSQLDB
    • To learn how to run a Grails  app on Glassfish and mySQL
      see: href="http://weblogs.java.net/blog/arungupta/archive/2008/04/totd_31_crud_ap.html">TOTD
      #31: CRUD Application using Grails - Hosted on GlassFish and MySQL
    • Grails framework

    • Groovy
    • href="http://dev.mysql.com/doc/refman/5.0/en/mysql-commands.html">MySQL
      commands




    Related Topics >>

    Comments

    You may also want to take a look at the Grails Pet Store.

    Thanks, yes that's interesting. My example isn't meant to be a Pet Store port btw, just a simple sample online catalog using grails. I've done similar sample online catalogs using Java EE, Spring, Seam, VWP, JRuby, Jmaki

    Excellent article! Thanks a lot.