 |
Carol McDonald's Blog
As a Java Technology Evangelist at Sun Microsystems, Carol McDonald has spoken at various conferences including JavaOne, Java University, Sun Tech Days, Sun Network, Sun Code Camps, JDJEdge, and JUGs including Machester, Boston, Maine, Cologne, FAA, Richmond, Memphis, D.C... Carol blogs about the latest technologies that she is speaking about at http://weblogs.java.net/blog/caroljmcdonald/.
Before returning to Sun in 2007, Carol worked 2 1/2 yrs as an Architect on massive OLTP Spring/hibernate application to manage > 10 mill loans for the consumer credit division of a leading automoblile manufacturer and a leading bank.
Before joining Sun the first time in 1999 Carol worked on Pharmaceutical Intranet applications for Roche in Switzerland, a Telecom Network Management Application for Digital (now HP) in France, a X.400 Email Server for IBM in Germany, and as a student intern for the National Security Agency. Carol holds a M.S. in Computer Science from the University of Tennessee, a B.S. in Geology from Vanderbilt University, and is a Sun Certified Java Architect and Java Language Programmer. Carol is also Fluent in French and German.
example using jMaki and RESTful Web Services
Posted by caroljmcdonald on July 18, 2008 at 04:02 PM | Permalink
| Comments (0)
Sample Application using jMaki and the Java Persistence APIs
a Dynamic Ajax table example using jMaki
and RESTful Web Services on Glassfish
This Sample Catalog app demonstrates a RESTful Web Service, coded using
JAX-RS: Java API
for RESTful Web Services (JSR-311) and Java
Persistence API,
which provides a list
of customers, and a jMaki
client which gets and displays the Web Service responses in
a dynamic Ajax table.
Download
the jMaki Sample Application Code
jMaki is an Ajax framework
that
provides a lightweight model for creating JavaScript centric
Ajax-enabled web applications. jMaki provides wrapped
widgets that can be used as JavaServer Pages tags, as JavaServer
Faces components, within a Phobos application, or with PHP. This sample
applicaton uses jMaki with JavaServer Pages.
JAX-RS provides a
standardized API for building RESTful web services in Java. Central to
the RESTful architecture is the concept of resources identified by
universal resource identifiers (URIs). The API provides a set of
annotations which you can add to Plain Old Java Objects (POJOs)
to expose web resources identified by URIs .
Explanation of the usage of jMaki and JAX-RS in a sample Catalog
Application
The image below shows the Customer Listing page, which allows the user
to
page through a list of customers.
jMaki dataTable widget
With jMaki and JavaServer Pages, you can easily include wrapped
widgets
from ajax toolkits into a JavaServer Page as a custom JSP tag. With
the Netbeans jMaki plugin you can drag jMaki widgets from the
Palette into a JSP. jMaki standardizes widget data and event models
to simplify the
programming model and to simplify interactions between widgets.
The sample application's index.jsp page uses a jMaki yahoo.dataTable
widget to display a list of
customers in a dynamic table.
The jMaki table widgets (there is also a jMaki dojo table
widget) are useful when you want to show a set of
results in tabular data on a web page. Table widgets provide
sortable columns, row selection, and they can
be updated using jMaki publish subscribe events.
In the List.jsp
web page the dataTable is defined as shown below: (Note: Red colors
are for jMaki
tags or variables,
and Green
for my code
or variables)
Code Sample from: index.jsp |
<a:widget
name="yahoo.dataTable"
subscribe="/table"
service="webresources/customers/jMakiTable"/>
|
To determine the data format and events for the
table you can refer to the jMaki
Table Data Model or look at
the widget.json file for the table widget. This file is located in the
resources/yahoo/dataTable directory.
The service
attribute references the customers/jMakiTable RESTful web
service
which returns the data to be
included
in the table. The data for the table should be a
JSON object containing an object of
columns and an array of row arrays. The column names need a unique id
which is then used in the data to associate it with a given row. An
example for a table of companies is shown below:
Code Sample from: widget.json |
{
'columns':[
{'label' :'Company', 'id' : 'name'},
{'label':'City', 'id' : 'city'},
{'label':'City', 'id' :
'state'}
],
'rows':[
{'name' : 'Sun Microsystems', 'city' : 'Santa
Clara', 'state' : 'CA'},
{'name' : 'IBM', 'city' :
'Raleigh','state' :
'NC'}
]
}
|
The subscribe="/table"
attribute specifies a topic that events can be
sent to. Publish and subscribe events can be used to tie widgets
together (more on this later).
RESTful Web Services with JAX-RS
The dataTable's service
attribute references the URI webresources/customers/jMakiTable for the customers jMakiTable
RESTful web service. The customers RESTful web
service was generated using Netbeans 6.1 as explained in the Generating
RESTful Web Services from Entity Classes tutorial.
Using Netbeans 6.1 you can generate JPA Entity Classes from Database
tables, then you can Generate RESTful Web Services from Entity
Classes, and then you can test the Web Services with a browser
interface. The customers RESTful web
service was generated from the customer data table which comes already
created in the Java DB with Netbeans. I added the jMakiTable
method to the generated customers Web Service, in order to return
the customers in the jMaki table format. I followed the jMakiBackend
example which comes with Jersey
(the JAX-RS reference implementation)
which is expained in Japods blog: jMaki
Widgets Talking To Jersey Resources In JSON.
Below is a snippet from the CustomersResource.java
class which was generated by the Netbeans "Generate RESTful Web
Services
from Entity Classes" feature :
Code Sample from: CustomersResource.java |
// Service URI path
"/customers/"
@Path("/customers/")
public class CustomersResource
{
@GET
@ProduceMime("application/json")
public CustomersConverter
get(@QueryParam("start")
@DefaultValue("0")
int start, @QueryParam("max")
@DefaultValue("4") int max, @QueryParam("expandLevel")
@DefaultValue("1") int expandLevel, @QueryParam("query")
@DefaultValue("SELECT e FROM Customer e") String query) {
try {
CustomersConverter custs = new CustomersConverter(
getEntities(start,
max, query),
context.getAbsolutePath(), expandLevel);
return custs;
} finally {
PersistenceService.getInstance().close();
}
}
|
The CustomersResource
represents a list of customers. The CustomersResource
get method
returns a list of Customer objects in JSON
format.
- To address a resource in REST you specify its URI.
@Path is
a JAX-RS annotation that identifies the URI path for the resource. For
the CustomersResource
the URI path is /customers/.
@GET specifies
that the get
method supports the HTTP GET method.
@ProduceMime
specifies the MIME types that a method can produce.
Here,
the annotation specifies that the get
method returns a JSONArray object. The CustomersConverter
class is a JAXB
annotated class which is used to marshal a list of Customer objects
into XML or JSON
format. The getEntities method
returns a list of Customer entity objects and is explained
below.
@QueryParam
specifies
input parameters for methods. When the method is invoked, the
input value will be injected into the corresponding input
argument.
@DefaultValue
specifies a default value for an arguement if no
input
value is given.
Here is an example of an HTTP request for this Web Service:
Request: GET
http://host/jMakiRest/webresources/customers/?start=0
|
Here is an example of an HTTP response for this Web Service:
Received:
{"customers":
{"@uri":"http://host/jMakiRest/webresources/customers/",
"customer":[
{"@uri":"http://host/jMakiRest/webresources/customers/1/",
"name":"JumboCom",
"city":"Fort
Lauderdale",
"state":"FL",
"zip":"33015"},
{"@uri":"http://host/jMakiRest/webresources/customers/2/",
"name":"Livermore Enterprises",
"city":"Miami",
"state":"FL",
"zip":"33055"}
]
}
}
|
Below is the getTable method
from the CustomersResource.java
class, which returns a list of Customers in the jMaki JSON
table format.
Code Sample from: CustomersResource.java |
public class CustomersResource
{
. . .
@GET
@Path("/jMakiTable")
@ProduceMime("application/json")
public CustomerTableModel getTable(@QueryParam("start")
@DefaultValue("0")
int start, @QueryParam("max")
@DefaultValue("4") int max, @QueryParam("expandLevel")
@DefaultValue("1") int expandLevel, @QueryParam("query")
@DefaultValue("SELECT e FROM Customer e") String query) {
CustomersConverter custs = get(start,
max,
expandLevel, query);
return new CustomerTableModel(custs.getCustomer());
}
|
The getTable
method calls the CustomersResource
get
method, explained above, to get a list of Customer Entities which
are used to create a CustomerTableModel
class. The CustomerTableModel
class is a JAXB annotated
class, used to marshal a list of Customer objects into the jMaki
JSON table format. A snippet of the CustomerTableModel
class is shown below:
Code Sample from: CustomerTableModel.java |
@XmlRootElement
public class CustomerTableModel {
public static class JMakiTableHeader {
public String id;
public String label;
public
JMakiTableHeader(String id,
String
label) {
this.id = id;
this.label = label;
}
}
public List<JMakiTableHeader> columns =
initHeaders();
public List<CustomerConverter> rows;
. ..
|
Java Persistence Query API
The CustomersResource getEntities
method
uses the Java Persistence API Query object
to return a list of customers.
Code Sample from: CustomersResource.java |
@Path("/customers/")
public class CustomersResource
{
.
. .
protected Collection<Customer> getEntities(int
start, int max, String query) {
PersistenceService
ps = PersistenceService.getInstance();
Query query = ps.createQuery(query);
query.setFirstResult(start);
query.setMaxResults(max);
return query.getResultList();
}
|
The Java
Persistence Query
APIs are used to create and execute queries that can return a
list of results. The JPA Query interface provides
support for pagination via the setFirstResult() and setMaxResults()
methods: query.setMaxResults(int maxResult)
sets the maximum number of results to retrieve. query.setFirstResult(int startPosition)
sets the position of the first result to retrieve.
In the code below, we show the Customer
entity class which maps to the CUSTOMER table that stores the
customer instances. This is a
typical Java Persistence entity object. There are two requirements for
an entity:
- annotating the class with an
@Entity
annotation.
- annotating the primary key identifier with
@Id
Because the fields name, description.... are basic mappings from the
object fields to columns of the same name in the database table, they
don't have to be annotated.
For more information on Netbeans and JPA see basics of
developing a web application using Java™ Persistence API.
Code Sample from: Customer.java |
@Entity
public class Customer
implements Serializable {
@Id
private Integer customerId;
private String name;
private String addressline1;
private String city;
private String state;
private String zip;
public Customer() { }
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
|
jMaki Publish Subscribe events
jMaki publish subscribe events tie widgets actions together. The sample
app
uses two jMaki yahoo.button widgets
which publish to the
/button/previous,
/button/next topics
when the respective button is clicked:
Code Sample from: List.jsp |
<a:widget
name="yahoo.button" value="{label : '<<',
action : {topic
: '/button/previous'}}"
/>
<a:widget
name="yahoo.button" value="{label : '>>',
action : {topic
: '/button/next'}}"
/>
|
Events in jMaki are handled by jMaki Glue , which allows JavaScript
components to talk to each
other. You put function listeners which Subscribe to topics that your
widgets Publish to in a file called glue.js (to read more about this
see A practical
guide to jMaki Events ).
Connecting the listener to the handler
The listener handler for the /button/next topic is
shown below. First you declare the topic to listen to and then the
listener function which will handle the notification. The /button/next listener
handler increments the page number and then calls the getNextPage
funtion.
Code Sample from: glue.js |
var page= 0;
var start= 0;
var batchSize=4;
jmaki.subscribe("/button/next",
function(args) {
page =page + 1;
getNextPage(page);
});
jmaki.subscribe("/button/previous",
function(args) {
page =page - 1;
if (page < 0) page = 0;
getNextPage(page);
});
function getNextPage(page)
{
start = page * batchSize;
jmaki.doAjax({method:
"POST",
url: "webresources/customers/?start="+encodeURIComponent(start),
callback :
function(req)
{
var
respObj = eval('('+ req.responseText +')');
var rows = respObj.customers.customer;
jmaki.publish("/table/clear", { });
for(j=0;j<rows.length;j++) {
var row = rows[j];
jmaki.publish("/table/addRow",{
value:
row
});
}
}
});
}
|
The getNextPage
function uses jmaki.doAjax,
which
provides an easy way to make an XMLHttpRequest, to call the /customers/
RESTful
Web Service passing the start index as a URI
parameter. The callback function
uses eval to convert the XMLHttpRequest response
into a JSON object. Then jmaki.publish
is called to publish the returned customer
JSON objects to the /table/addRow topic.
The yahoo.dataTable
widget subscribes to the table topic.
Subscribe events allow you to manipulate a given instance of a widget.
The event names are appended to the the subscribe topic name following
a "/". For example "/table/addRow"
will call the yahoo.dataTable addRow
function which will add the payload value passed to the widget to
the the table. This will cause the returned customer
JSON object to be displayed in the table on the html page.
Conclusion
This concludes the sample application which demonstrates a
RESTful Web Service, coded using
JAX-RS: Java API
for RESTful Web Services (JSR-311) ,
which provides a list
of customers, and a jMaki
client which gets and displays the Web Service responses in
a dynamic Ajax table.
Configuration of the Application
for jMaki, JPA, Netbeans 6.1 and Glassfish V2
- Download
and install NetBeans 6.1 bundled with GlassFish V2
- Alternatively you can Download
and install GlassFish V2 separately.
- Download
and install the jMaki
plug-in in the NetBeans update center.
Open and Run the Sample code:
- Download the sample
code and extract its contents. You should now see the newly
extracted directory as
<sample_install_dir>/jmakiRest,
where <sample_install_dir> is the directory where
you installed 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:\jmakiRest.
- Start the NetBeans IDE. Click Open Project in the File menu and
select the
jmakiRest directory you just
unzipped.
- Build the project as follows:
- Right click the
jmakiRest node in
the
Projects window.
- Select Clean and Build Project.
- Run the project as follows:
- Right click the
jmakiRest node in
the
Projects window.
- Select Run Project.
When you run the project, your browser should display the opening page
of the Sample Application (at
http://localhost:8080/jmakiRest/).
If you want to create your own jMaki
application:
- check out Arun Gupta's blog
and screencasts.
References:
Sample Store Catalog using using Groovy and Grails and the Java Persistence API on Glassfish with MySQL
Posted by caroljmcdonald on July 07, 2008 at 07:54 PM | Permalink
| Comments (0)
grailsexample
Sample Store Catalog using using Groovy and Grails and the Java
Persistence API on Glassfish with MySQL
I modified this Groovy
and Grails Catalog Sample application to use JPA entity java
classes instead of Groovy domain classes. I followed the steps in
this InfoQ article Grails + EJB
Domain Models Step-by-Step and I was really surprised at how
easy it was !
download Catalog sample code
Overview of the Technologies and Frameworks in the Sample Application
The
Java Persistence API
provides a POJO-based persistence model for
Java EE and Java SE applications. It handles the details of how
relational data is mapped to Java objects, and it standardizes
Object/Relational (O/R) mapping.
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.

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.
The Model - JPA Entity Classes
The Model is your application's persistent business domain objects.
A JPA Entity
instance represents a row in a database table. Item
is an Entity class -- a typical Java Persistence entity
object -- which maps to an ITEM table that stores the item instances.
The Item
class has a many-to-one relationship
with the Address
class, this is specified using the @ManyToOne annotation in
the Item
class and the @OneToMany(mappedBy = "address") annotation
in the Address
entity class shown below:
Code Sample from: model\Item.java
|
package model;
// import ....
@Entity
@Table(name = "item")
public class Item
implements Serializable{
@Id
private Long id;
private String name;
private String description;
private String imageurl;
private String imagethumburl;
private BigDecimal price;
@ManyToOne(optional
= false)
@JoinColumn(name = "address_id")
private Address address;
// getters and
setters ...
}
|
|
|
Code Sample from: model\Address.java
|
package model;
// import ....
@Entity
@Table(name = "address")
public class Address implements
Serializable{
@Id
private Long id;
private String street1;
private String street2;
private String city;
private String state;
private String zip;
private BigDecimal latitude;
private BigDecimal longitude;
private BigInteger version;
@OneToMany(mappedBy = "address")
private Collection<Item> items ;
// getters and setters ...
}
|
|
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)
);
|
Using the Java Persistence API With Grails and MySQL
Entering the Grails command
> grails create-app catalog
creates a standard directory structure for a grails application named
catalog. After you have your directory structure , to use JPA
entities with a grails application:
- copy your entity files into the application name\src\java
directory, in this case I copied the model.Item and the
model.Address java files into the catalog\src\java\model
directory.
- copy the MySQL jdbc driver mysql-connector-java-5.1.6-bin.jar
into the directory catalog\lib
.
- modify the DataSource.groovy
file in the catalog\grails-app\conf
directory to use MySQL as the data base and the
GrailsAnnotationConfiguration
class to use the annotations in the JPA entities as shown below :
| Code Sample from: catalog\grails-app\conf\DataSource.groovy |
import
org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration
dataSource {
configClass =
GrailsAnnotationConfiguration.class
pooled = false
driverClassName =
"com.mysql.jdbc.Driver"
username = "root"
password = ""
dialect =
"org.hibernate.dialect.MySQL5InnoDBDialect"
}
hibernate {
cache.use_second_level_cache=true
cache.use_query_cache=true
cache.provider_class='org.hibernate.cache.EhCacheProvider'
}
// environment specific settings
environments {
development {
dataSource {
dbCreate =
"update"
url = "jdbc:mysql://localhost/petcatalog"
}
}
test {
dataSource {
dbCreate =
"update"
url =
"jdbc:mysql://localhost/petcatalog"
}
}
production {
dataSource {
dbCreate =
"update"
url =
"jdbc:mysql://localhost/petcatalog"
}
}
}
|
- In order for Grails to recognize the JPA Entity classes as domain
classes, add the hibernate.cfg.xml file shown
below to the catalog\grails-app\conf\hibernate directory:
| Code Sample from: catalog\grails-app\conf\hibernate\hibernate.cfg.xml
|
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate
Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping package="model"
/>
<mapping
class="model.Item" />
<mapping
class="model.Address" />
</session-factory>
</hibernate-configuration>
|
The Controller
Entering the Grails command (in the directory catalog)
> grails generate-controller model.Item
will generate the ItemController.groovy
class for the model.Item
entity class.
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 the
list action method in the item controller class
shown below. 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 ItemController
list
action 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 the ItemController
code the index
action method redirects to the list
action. The ItemController
list action
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
Entering the Grails command (in the directory catalog)
> grails generate-views model.Item
will generate the create.gsp ,
edit.gsp, list.gsp, show.gsp groovy server pages for the model.Item entity class.
The view layer generates a web
page, using data from domain objects provided by the controller. In
Grails, the view is rendered using 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\views\item\list.gsp
|
<table>
<thead>
<tr>
<g:sortableColumn
property="name" title="Name" />
<g:sortableColumn
property="imagethumburl" title="Photo" />
<g:sortableColumn
property="price" title="Price" />
</tr>
</thead>
<tbody>
<g:each
in="${itemList}"
status="i"
var="item">
<tr class="${(i % 2) == 0
? 'odd' : 'even'}">
<td>
<g:link
action="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:paginate
total="${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 sortableColumn
tag renders a sortable column to support sorting in tables.
<g:each
in="${itemList}" status="i"
var="item">
loops through each object in the itemList variable,
which is an ordered ArrayList of Item model
objects, and assigns each Item
model object to the item variable.
<g:link
action="show"
id="${item.id}">${item.name?.encodeAsHTML()}</g:link>
the
<g:link> 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 href="/catalog/item/show/2">Friendly Cat</a>
<img
src="${createLinkTo(dir:'images',file:item.imagethumburl)}"/>
The createLinkTo
tag 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 show
action in the ItemController
passing 1 to the method as the id of
the params parameter
hash. The show
action of the ItemController class
is shown below. The ItemController
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 = Item.get( params.id )
if(!item) {
flash.message = "Item not found with id
${params.id}"
redirect(action:list)
}
else { return [ item : item ] }
}
|
The show
action method calls the Item.get()
method
which queries the items table returning the item instance
variable corresponding to the item with the attribute id
(primary key)
equal to the id
parameter. This is the equivalent of the following sql : select * from items where id='1' .
The item variable
is automatically made available to the Show view by the framework.
The Show View GSP
After executing
code in the action, the show action
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 description attribute.
<img
src="${createLinkTo(dir:'images',file:item.imageurl)}" />
generates an HTML
image tag for the item's imageurl
attribute.
${item?.address?.city}
displays the value of the item's address city attribute.
The image below shows the resulting page for the url
http://host/catalog/item/show/105, which displays the item 105's
details:
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 JPA Entities
which are retrieved using Item
Controller action methods, and
displayed using Item View GSPs.
Setting Things Up and Running the Sample code on MySQL and Jetty:
- 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).
- Download and
install Grails.
- 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 a MySQL
configuration.
- Start the MySQL database as follows:
> mysqld_safe --user root
--console
- Create the pet-catalog database:
> mysqladmin
create petcatalog --user root
- Create
the tables in the MySQL pet-catalog database as follows:
- 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:
- Use the WAR file in
<sample_install_dir>/Catalog/Catalog.war
or Create a WAR file:
- 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)
- Enter the URL http://localhost:8080/
catalog-0.1/
in
your browser, you should see the home page of the Sample
Application.
For more information:
Comet Slideshow example on Grizzly
Posted by caroljmcdonald on July 01, 2008 at 02:37 PM | Permalink
| Comments (0)
Comet Slideshow example on Grizzly
A Comet Slideshow example using dojo, Comet, Bayeux, on Grizzly
with Glassfish
This Sample Slideshow app demonstrates the usage of the dojo Ajax
framework, Comet, Bayeux, with Grizzly and Glassfish.
Download
the dojo Comet Sample Application Code
dojo
is an open source DHTML toolkit written in JavaScript. It includes many
utilities that go beyond Ajax, for example the dojox.comet module
simplifies programming comet applications. Comet is a term coined by
Alex Russell to describe applications where the Server pushes
data to the client. For example in the diagram below on the left
you see Ajax polling which uses synchronous
requests/responses to get events from the server. Comet
uses long-lived previously-opened HTTP connections to "push" data to
the client at any time, not only in response to user input.

Grizzly is an HTTP
framework which uses the Java™ NIO API to provide fast HTTP processing
. Grizzly provides Comet (long-lived streaming HTTP connections)
support built on top of
Grizzly's Asynchronous
Request Processing (ARP). With Grizzly ARP, each Comet
request isn't holding onto a thread which gives
scalability. Bayeux
is a protocol for routing JSON encoded events between clients and servers in a publish
subscribe model. Grizzly provides an implementation of Bayeux,
which makes it really easy to build Comet applications with dojo, you
just configure Glassfish for Comet and configure your Web Application's
web.xml for the Grizzly Bayeux servlet then you can use the
dojox cometd publish and subscribe methods to send and receive Comet
events as described in more detail below.

Grizzly comes with Glassfish , or it can be used separately. To use
Comet with Glassfish you just need to add the bold red line to
the
Glassfish config domain.xml:
Code Sample from: index.html |
<http-listener acceptor-threads="1" address="0.0.0.0" blocking-enabled="false" default-virtual-server="server" enabled="true" family="inet" id="http-listener-1" port="8080" security-enabled="false" server-name="" xpowered-by="true"> <property name="cometSupport" value="true"/> </http-listener>
|
Enabling Bayeux in GlassFish
to enable Bayeux on Glassfish, add the following to your Web
application web.xml :
Code Sample from: index.html |
<servlet> <servlet-name>Grizzly Cometd Servlet</servlet-name> <servlet-class> com.sun.grizzly.cometd.servlet.CometdServlet </servlet-class> <init-param> <description> expirationDelay is the long delay before a request is resumed. -1 means never. </description> <param-name>expirationDelay</param-name> <param-value>-1</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Grizzly Cometd Servlet</servlet-name> <url-pattern>/cometd/*</url-pattern> </servlet-mapping>
|
Package your war and deploy it on Glassfish, then every
request sent to your war's context-path/cometd/
will be
serviced by the Grizzly Bayeux runtime.
Explanation of the usage of dojox cometd in the sample Slideshow
Application
I modified the comet chat example from
here (originally written by Greg Wilkins), to share a
slideshow presentation among all subscribed
clients. The image below shows the Comet Slideshow page, which allows
the users
to share a Slideshow and chat at the same time.

Quick installation and use of dojo with Netbeans
There are 3 ways to install dojo which you can read about at in the
book of dojo. A quick and easy way to use dojo with Netbeans is to
download the JavaScript libraries from http://dojotoolkit.org/downloads.
Create a new NetBeans Web Applications project. Extract the dojo
toolkit into the project web directory: .../web , then rename
dojo-release-1.1.1/ to src/ this will give you the project
structure shown below. I have already done this for the sample
project so you do not have to download dojo in order to run the sample.

Loading base dojo and required modules into an application
In order to load dojo into your application, put the relative
path to the dojo.js file in a script element in the head
section of your HTML page as shown below:
Code Sample from: index.html |
<script type="text/javascript"
src="src/dojo/dojo.js"></script>
<script type="text/javascript" src="chat.js"></script>
|
This script element will load the base dojo script which gives you
access to all the dojo functionality. The rest of the Java Script for
this application is in the file chat.js.
Next in chat.js the application specifies which dojo modules to
load, using the dojo.require function (kind of like import
in Java):
Code Sample from: chat.js |
dojo.require("dojox.cometd");
|
Dojo is organized into three major layers: Dojo Core, Dijit, and
DojoX. DojoX builds on Dojo Core and provides newer
extensions to the Dojo toolkit. DojoX cometd
implements a
Bayeux protocol client for use with a Bayeux server.
Initializing a connection between the dojo client and the Grizzly
BayeuxServlet
When a user first loads the slideshow application, he can enter a
username and join a slideshow session.

When a user clicks on the Join button, the join
javascript function is called. In the join
function, the call to dojox.cometd.init initialises a
connection to the given Comet server, in this case with the Glassfish
Grizzly Bayeux servlet (note /cometd/* is the url-pattern for the
Grizzly Cometd Servlet configured in the web.xml for the
application).
Code Sample from: chat.js |
var room = {
...
join: function(name){
dojox.cometd.init("/cometd");
dojox.cometd.subscribe("/chat/demo", room, "_chat");
dojox.cometd.publish("/chat/demo",
{ user: room._username,
join: true, chat :
room._username+" has joined"});
}
|
The dojox.cometd.subscribe line subscribes
the _chat callback
function to the /chat/demo channel. Any time a message is
sent to the /chat/demo channel the _chat
function will be called.
The dojox.cometd.publish line
publishes the message that the user (the name that was entered
with the join button) has joined the /chat/demo channel.
Subscribers to the /chat/demo channel
will get this message.
Publishing the next slide for the Comet Slideshow
When the user clicks on the "Next Slide" button shown below, a
javascript funtion is called which publishes the url for the next slide.

Code Sample from: index.html |
<input id="previousB" class="button"
type="submit" name="previous" value="Previous Slide"/>
<input id="nextB"
class="button" type="submit" name="next" value="Next Slide"/>
|
When the user clicks on the Next Slide button, the javascript
function shown below is called. This function calls room.next passing
the url for the next slide. The function then increments the index for
the next slide. The urls for the slides are stored in the slideUrls
array shown below.
Code Sample from: widget.json |
var room = {
...
_init:
function(){
var slideUrls=[
"/dojoComet/images/image0.jpg",
"/dojoComet/images/image1.jpg",
"/dojoComet/images/image2.jpg",
"/dojoComet/images/image3.jpg",
"/dojoComet/images/image4.jpg",
"/dojoComet/images/image5.jpg"];
var i=0;
element=dojo.byId('nextB');
element.onclick = function(){
room.next( slideUrls[i]);
if (i>=slideUrls.length){i=0;}
else {i++;}
}
element=dojo.byId('previousB');
element.onclick = function(){
room.next( slideUrls[i]);
if (i<=0){i=0;}
else {i--;}
}
}
...
|
The function room.next, shown below, calls dojox.cometd.publish
to publish the next slide url (input argument) to the /chat/demo
channel. Subscribers to the /chat/demo
channel will get this message.
Code Sample from: chat.js |
var room = {
...
next: function(text){
dojox.cometd.publish("/chat/demo", {slide: text});
}
...
}
|
When a message is published to a Bayeux
channel on the server, it is delivered to all clients
subscribed to that channel, in this case to the "/chat/demo" channel . In the room.join
function shown before dojox.cometd.subscribe("/chat/demo", room,
"_chat") was called to subscribe the _chat callback function to
the /chat/demo channel. The _chat
callback function, shown below, is called with the
published message as an input argument. The _chat callback
function updates the browser page by setting the slide dom
element innerHTML to an html img tag with the slide url
from the published message "<img
src='" + slideUrl + "'/>" . This updates the browser page
with the image corresponding to the slide URL which was published.
Code Sample from: chat.js |
var room = {
...
_chat: function(message){
var slide=dojo.byId('slide');
var
slideUrl=message.data.slide;
slide.innerHTML ="<img
src='" + slideUrl + "'/>";
...
}
|
Conclusion
This concludes the sample application which demonstrates the usage of
the dojo Ajax
framework, Comet, Bayeux, with Grizzly and Glassfish.
Running the Sample Code
The sample code is available as a NetBeans project. You can build
and run the sample code using the NetBeans IDE.
Setting Things Up
- Download
and install NetBeans 6.1 bundled with GlassFish V2
- Alternatively you can Download
and install GlassFish V2 separately.
- To use
Comet with Glassfish you just need to add the bold red line to
the
Glassfish config domain.xml (in the directory
glassfish/domains/domain1/config ):
Code Sample from: index.html |
<http-listener acceptor-threads="1" address="0.0.0.0" blocking-enabled="false" default-virtual-server="server" enabled="true" family="inet" id="http-listener-1" port="8080" security-enabled="false" server-name="" xpowered-by="true"> <property name="cometSupport" value="true"/> </http-listener>
|
- Bayeux and dojo are already configured in the sample code.
Open and Run the Sample code:
- Download the sample
code and extract its contents. You should now see the newly
extracted directory as
<sample_install_dir>/dojoComet,
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:\dojoComet.
- Start the NetBeans IDE. Click Open Project in the File menu and
select the
dojoComet directory you just
unzipped.
- Build the project as follows:
- Right click the
dojoComet node in
the
Projects window.
- Select Clean and Build Project.
- Run the project as follows:
- Right click the
dojoComet node in
the
Projects window.
- Select Run Project.
When you run the project, your browser should display the opening page
of the Sample Application (at
http://localhost:8080/dojoComet/). Open
another browser and set that url to http://localhost:8080/dojoComet/
then enter a name and click on the join button in both browser windows.
Then click on the
next slide button in one browser window. Both browsers should get
updated with the next
slide.
For more Information:
jMaki Presentation slides and Sample code
Posted by caroljmcdonald on June 06, 2008 at 04:26 PM | Permalink
| Comments (2)
jMaki Presentation slides and Sample code
jMaki is a lightweight
framework for creating Web 2.0 applications using standards-based
technologies such as CSS, HTML, and JavaScript. I have updated the Sun
Tech Days jMaki presentation I am giving in Manilla with
explanatory notes for the slides. I have also updated the Dynamic
Ajax table example using jMaki and Java Persistence APIs on Glassfish
on my blog. Download the presentation
and sample code.
Deploy the sample code as
described in the blog, try out the example, look at the code, read the
slides, learn about the jMaki framework.
Sample Store Catalog using using Groovy and Grails
Posted by caroljmcdonald on April 28, 2008 at 07:35 PM | Permalink
| Comments (3)
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.
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.
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.
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.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 Item
class has a many-to-one relationship
with the Address
class. In Grails hasMany
is 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]
}
|
|
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 the
list |