Skip navigation

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.
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 anddynamic language for the Java Virtual Machine, itcompiles 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



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


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 Item.groovyclass shown below corresponding to the item table.

After model code generation you have to add the domain object's attributes and relationships. The Itemclass has a many-to-one relationship with the Addressclass. In Grails hasManyis the many end of a many-to-one  relationship.


      
        
Code Sample from: domain\Item.groovy

class Item {
  Long id
  String name
  String description
  String imageurl
  String imagethumburl
  BigDecimal price
  Address address
}
   


 
        
Code Sample from: 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

        
SQL  Sample for items table

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/app/controller/action/id .  For example the URL http://host/catalog/item/list calls thelist action method in the item controller class shown below.     Grails Scaffoldingprovides 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 ItemControllerlistaction renders a view with a paginated list of item objects.

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

class ItemController{

 
def index = { redirect(action:list,params:params) }

  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 theItemControllercode the  indexaction method redirects to the listaction.  The ItemControllerlistaction method calls the Item.list()method which returns an ArrayList of item objects retrieved from the item database table . If there are more than params.max objects in the table, Grails creates next and previous pagination links automatically. The itemList 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 usingGroovy 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\views\item\list.gsp

<table>
   <thead>
     <tr>
        <g:sortableColumnproperty="name" title="Name" />
        <g:sortableColumn property="imagethumburl" title="Photo" />
        <g:sortableColumn property="price" title="Price" />
     </tr>
   </thead>
   <tbody>
     <g:eachin="${itemList}" status="i" var="item">
        <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
           <td>
            <g:linkaction="show" id="${item.id}">
                ${item.name?.encodeAsHTML()}</g:link>
           </td>
           <td>
             <img src="${createLinkTo(dir:'images',file:item.imagethumburl)}"/>
           </td>
           <td>${item.price?.encodeAsHTML()}</td>
        </tr>
     </g:each>
  </tbody>
 </table>

<div class="paginateButtons">
 <g:paginatetotal="${Item.count()}" />
</div>


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. <g: are GroovyTags.
  

<g:sortableColumn
       The sortableColumntag renders a sortable column to support sorting in tables.

<g:each in="${itemList}" status="i" var="item">
loops through each object in the itemListvariable, which is an ordered ArrayList of Itemmodel objects,  and assigns each Itemmodel object to the itemvariable.
 
<g:link action="show" id="${item.id}">${item.name?.encodeAsHTML()}</g:link>  
the <g:link> GroovyTag creates an html anchor taghref 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 variableitem
<a href="/catalog/item/show/2">Friendly Cat</a>
<img src="${createLinkTo(dir:'images',file:item.imagethumburl)}"/>  
The createLinkTotag generates an HTML link for the item's imagethumburl attribute. 

${item.price?.encodeAsHTML()}
displays the value of the item 's price attribute as escaped HTML text.

<g:paginate total="${Item.count()}" /> 
The 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/item/show/1  ( http://host/controller/action/id )  will route to the showaction in the ItemControllerpassing 1 to the method as the id of theparamsparameter hash. The showaction of the ItemControllerclass is shown below. The ItemControllershowaction 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 = Item.get( params.id)

   if(!item) {
      flash.message = "Item not found with id ${params.id}"
      redirect(action:list)
   }
   else { return [ item : item ] }
 }



The showaction method  calls the Item.get()method which queries the items table returning the iteminstance variable corresponding to the item with the attributeid(primary key) equal to the  idparameter. This is the equivalent of the following sql : select * from items where id='1' . The itemvariable is automatically made available to the Show view by the framework.

 

The Show View GSP

After executing code in the action, the showaction renders the app/views/item/show.gsp . Below is the GSP for the item show view :


        
Code Sample from: grails-app\views\item\show.gsp

<h2> Detail of item</h2>

<table>
<tbody>
    <tr class="prop">
      <td valign="top" class="name">Name:</td>                          
        <td valign="top" class="value">${item.name}</td>                          
      </tr>                   
      <tr class="prop">
        <td valign="top" class="name">
           Description:
        </td>                           
          <td valign="top" class="value">
           ${item.description}
        </td>                          
      </tr>                       
      <tr class="prop">
        <td valign="top" class="name">Imageurl:</td>                          
          <td valign="top" class="value">
            <img src="${createLinkTo(dir:'images',file:item.imageurl)}" />
        </td>                           
      </tr>                                           
      <tr class="prop">
        <td valign="top" class="name">Price:</td>                           
          <td valign="top" class="value">$ ${item.price}</td>                           
      </tr>
    <tr class="prop">
        <td valign="top" class="name">Address:</td>                           
          <td valign="top" class="value">
          ${item?.address?.street1}, ${item?.address?.city},    
            ${item?.address?.state}
        </td>                          
      </tr>                       
  </tbody>
</table>  



${item.description}
displays the value of the item 's descriptionattribute.
<img src="${createLinkTo(dir:'images',file:item.imageurl)}" />  
generates an HTML image tag for theitem's imageurl attribute.
${item?.address?.city}
displays the value of the item'saddress cityattribute.

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

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: 
<meta name="layout" content="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

<table>
  <tr>
   <td>Pet Catalog</td>
   <td>
     <img src="${createLinkTo(dir:'images',file:'pet_logo.jpg')}"/>
   </td>
 </tr>
</table>




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 ViewGSPs.

 

Setting Things Up and Running the Sample code onMySQL and Jetty:

  1. If MySQL is already installed, then download GlassFish v2 UR1. Otherwise you can also Download GlassFish v2 UR1 and MySQL co-bundle from the usual Download Page (instructions).

  2. Download and install Grails.

  3. Download the sample code and extract its contents. You should now see the newly extracted directory as<sample_install_dir>/Catalog, where<sample_install_dir> 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 aMySQL configuration.

  4. Start the MySQL database as follows:

     
    • > mysqld_safe --user root --console

  5. Create the pet-catalog database:

     
    • > mysqladmin create petcatalog --user root

  6. Create the tables in the MySQL pet-catalog database as follows:

     
    • shell> mysqlpet-catalog< catalog.sql
      
    • using the file catalog.sql file from the/Catalog directory.

  7. Run the project as follows:
    in a command window in the /Catalog directory enter the command
  8. > 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<sample_install_dir>/Catalog/Catalog.war or Create a WAR file:
     
    • > grails war
      
  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



 

Speaking at CommunityOne 2008

Kito Mann and I  are speaking at CommunityOne 2008 on: "Examining a Sample Application Built in Three Ways: Java™ Platform, Enterprise Edition (Java EE Platform), Spring 2.5, and Seam 2.0 Deployed on the GlassFish™ Project". CommunityOne is the day before JavaOne (May 05), its free, and you can learn about a wide range of open source projects.
Our talk is May 05 12:25 - 13:20    Moscone South - Esplanade 305. Here is the abstract:
This session looks at the implementation of the same web application developed with three open source frameworks and highlights what was done differently with each one. First it explains the implementation of the sample application with JavaServer™ Faces and Enterprise JavaBeans™ 3.0 (EJB™ 3.0) technology and the Java™ Persistence API (JPA). Next it looks at how this application was developed with JavaServer Faces technology, the JPA, and Spring 2.5. Finally, it looks at this application developed with JavaServer Faces and EJB 3.0 technology, the JPA, and Seam 2.0. The presentation highlights differences in the frameworks, such as the Seam context model for stateful components. All three versions were deployed on GlassFish™ project V2, and the source code is available in my blog.

http://technorati.com/tag/JavaOne 
C1_170x93_SpeakerB.gif

 



 

Metro Hands-on Lab at JavaOne 2008

Fabian Ritzman, Martin Grebac and I  have developed a hands-on lab on Metro Web Services for JavaOne 2008. At JavaOne hands-on labs, you bring your own laptop, this allows you to easily take home and reuse the stuff you learn in the lab. We have a step by step lab doc with screenshots etc. that you can work through to familiarize yourself with Metro. Fabian and I will briefly explain and demonstrate the lab exercises, then you will complete them on your laptop. There will be proctors to help with any questions. Hope to see you there!  You can find out more about the lab here: https://www28.cplan.com/cc191/session_details.jsp?isid=296941&ilocation_id=191-1&ilanguage=english

The title of the lab is "Metro: Try Out Simple and Interoperable Web Services". Session ID is 3410. The lab takes place on Tuesday, 10:50 - 12:50.  Here is the complete abstract:

Metro is a high-performance, extensible, easy-to-use web service stack. You can use it for every type of web service, from simple to reliable, secured, and transacted web services that interoperate with .NET services. Metro bundles stable versions of the JAX-WS (Java™ API for XML Web Services) reference implementation and WSIT (Web Services Interoperability Technology).

JAX-WS is a fundamental technology for developing SOAP-based and RESTful Java technology-based web services. WSIT enables secure, reliable interoperability between Java technology-based web services and Microsoft’s Windows Communication Foundation.

This Hands-on Lab starts by developing a simple Metro web service and showing how to enhance this web service with Metro features such as reliability and security. The next part of the lab enables a web service client with Metro security features and has it interoperate with the previously built service. The lab shows the ease of development the NetBeans™ 6.0 release provides for achieving this.

The lab uses the NetBeans 6.0 release to modify and configure both the web service and the client, using Sun’s GlassFish™ project application server as the container. The lab uses WS-Reliability and WS-Security as examples of Metro’s secure, reliable features.

The lab comprises the following sections:

Introduction to Metro 
  • Develop and deploy a basic catalog web service to return a list of catalog items
  • Test the web service, using the Tester application provided by the GlassFish project
Metro Reliability 
  • Enable reliability on the catalog web service, and examine the messages
  • Develop and deploy a Metro client for the catalog web service, and configure the client for reliable access to the web service
Metro Security 
  • Enable security on the catalog web service, and examine the messages
  • Configure the Metro client for the catalog web service (from the previous exercise) for secure access to the secure web service

Prerequisites: some understanding of Servlets, XML, and SOAP

At JavaOne, this lab will be presented in Hall E (Room# 132).

Please bring your laptops to this lab as there no machines provided in this room.

System requirements: 
  • Supported OS: Windows 2000/XP, Solaris 10/11, Linux
  • Memory requirement: 768MB minimum, 1GB recommended
  • Disk space requirement: 300 MB

Software requirements:

Also please make sure to install the following software prior to coming to this lab: 
  • JDK 5.0 or 6
  • NetBeans 6.0.1 with Web & Java EE pack
  • GlassFish V2 UR1
Tags: Web Services, Metro,JavaOne 
170x93_Speaker_v4.gif

 


Filter Blog

By date: