Java Edge.2009.Grails.Web.Dev.Made.Easy
Transcript of Java Edge.2009.Grails.Web.Dev.Made.Easy
Web development made easy
By: Roi Aldaag,
Consultant & Architect
Grails
2
Agenda
• Introduction
• Demo
• Groovy 101
• Grails
• Google App Engine (GAE)
Introduction
4
Introduction
• What is Grails?
• Architecture
• Grails Goals
5
What is Grails?
• A full stack web framework
• Open Source (Apache 2.0 license)
• Based on Groovy
• Fully compatible with Java
2005 200911/200802/20082006
1.0Release
1.1.1Release
6
Architecture
Grails
Java EE Spring
The Java LanguageThe Java Development Kit
(JDK)
The Java Virtual Machine
Gro
ovy
Hibernate SiteMesh
7
Design Goals / NYAJWF
Grails
Full Stack
Convention / Configuration
AgilePhilosophy
SolidFoundations
JavaIntegration
Community
Productivity
8
Design Goals / NYAJWF
• Full stack
• Grails comes with a full development
environment
• Web server (Jetty / Tomcat)
• Database (HSQLDB)
• Testing (JUnit)
• Command line shell
• Grails console
9
Design Goals / NYAJWF
• Convention / Configuration
• Sensible defaults based on source code
• Defaults can be overriden with no XML
• Existing XML configurations can still be used
10
Design Goals / NYAJWF
• Agile philosophy
• Development is an interactive process
• Add / modify Controllers, Domains and Views
while application is running
• Refresh view to test results
• Zero turn-around
• No deployment / server restart required
• Rapid prototyping
• Scaffolding
11
Design Goals / NYAJWF
• Solid foundations
• Built on tested and proven OS technologies
• Spring framework
• Hibernate ORM
• SiteMesh page layout framework
• AJAX libraries: script.aculo.us, Rico, prototype
• HSQLDB
• Junit
• Minimizes learning curve
• Backed up by SpringSource
12
Design Goals / NYAJWF
• Java Integration
• Groovy code is compiled to bytecode
• Java code can be run as Groovy*
• GDK -> Groovy’s extention to JDK (~ 60
enhanced classes)
• GroovyClassLoader
• Loads and parses Groovy classes to be used
in Java classes
13
Web framework made easy
Web frameworks
in Java don’t
have to be:
14
Web framework made easy
• Frustrating
15
Web framework made easy
• Slow
16
Web framework made easy
• and cause you a
nervous breakdown…
17
Web framework made easy
• With Grails it can be like this:
18
Web framework made easy
• Or maybe more
like this …
19
Design Goals / NYAJWF
• Productivity
• Development is fun!
• Develop web applications much quicker
• Concentrate on business model
• Get instant feedback
• No XML configuration
• Ready to use development environment
Demo
Let Grails do the magic …
21
Demo
• So here is the initial Mockup…
22
Demo
• Ingredients:
1. a handful of
images
2. a pinch of mockup data
23
Demo
• More ingredients…
3. Five domain classes
+
Five controller classes
24
Demo
• and let Grails do the magic…
25
Demo
• It’s DEMO time!
26
Statistics
27
Demo
• … and we are done!
Groovy 101
Quick Groovy crash course
29
Groovy 101
• OO dynamic programming language
• A superset of the Java language
• Works seamlessly with Java libraries
• Most Java Code is syntactically valid Groovy
• Compiled to JVM bytecode
• Used as a scripting language for the JVM
2003 20092007
1.0 Release1.6.5 Release
James Strachan's Weblog
JSR 241
30
Groovy 101
• Compilation
• precompiled
• direct
JVM
31
Groovy 101
• Differences from Java (partial list)
• GDK extends JDK (e.g. GString)
• Parenthesis and Semicolons are optional
• Implicit return, getters and setters
• Anonymous inner classes not supported
• == equality not identity
• Default access of “public”
• Only runtime exceptions
32
Groovy 101
• Features (very partial list…)
• Dynamic typing
• Closures
• Operator Overloading
• Native support for RegEx
• Native support for markup languages
• Native support for testing (JUnit)
• Expressions embedded inside strings
33
Dynamic Typing
• Use def keyword when defining variables
(optional)
• At runtime, the appropriate type will be
used based on assigned value
def var = 1
assert var.class in java.lang.Integer
var = “Hello World”
assert var.class in java.lang.String
35
Closures
• What is a closure?
• An anonymous block of code
• Do not have to be declared in a class
• An object of type groovy.lang.Closure
• Assigned to variables
• Passed as method arguments
• Can reference variables within their scope
• Executed when it’s called—not when it’s
defined
36
Closures
• Syntax
• Must be enclosed by curly braces “{ }”
• May take a list of optional arguments
separated by “,”
• The symbol “->” separates args from body
• “it” represents single arg (-> not required)
{ [optional args ->] zero or more statements }
37
Closures
• Definition
{println “Hello World!”} // no args
{message -> println message} // untyped arg
{arg1, arg2 -> return arg1 + arg2} // untyped args
{println it} // implicit arg
• Assignment & Call
def p = {println it} // assign
p(“Hello World!”) // call
38
Expressions embedded inside strings (1/2)
• GString evaluates expressions embedded
within the string
• Expression is evaluated when string is accessed
• Uses ${...} notation
• “…” – evaluated ‘…’ – not evaluated
39
Expressions embedded inside strings (2/2)
def str = “JavaEdge2009"
def hello = "Hello, ${str}"
println hello // Hello JavaEdge 2009
println hello.class.name // org.codehaus.groovy.
// runtime.GStringImpl
def hello = „Hello, ${str}‟
println hello // Hello, ${str}
println hello.class.name // java.lang.String
40
Why Groovy?
public class Todo {
String name
String note
}
def todos = [
new Todo(name:"1", note:"one"),
new Todo(name:"2", note:"two"),
new Todo(name:"3", note:"three")
]
todos.each {
println "${it.name} ${it.note}“
}
Todo.groovy
• Example:
• Define Todo Class
• Create list
• Add 3 todo’s
• Print List
• Groovy: 12 LOC
41
Why Groovy?
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
public class Todo {
private String name;
private String note;
public Todo() {}
public Todo(String name, String note){
this.name = name;
this.note = note;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNote() {
return note;
}
• Java: 45 LOC
public void setNote(String note) {
this.note = note;
}
public static void main(String[] args){
List todos = new ArrayList();
todos.add(new Todo("1", "one"));
todos.add(new Todo("2", "two"));
todos.add(new Todo("3","three"));
for(Iterator iter =
todos.iterator();iter.hasNext();){
Todo todo = (Todo)iter.next();
System.out.println(todo.getName() +
" " + todo.getNote());
}
}
}
Todo.java
Grails Setup
43
Setup
Add Grails to PATH
PATH=$GRAILS_HOME/bin;$PATH
Customize Environment
GRAILS_HOME=/opt/grails
Install Grails
http://www.grails.org
Install JDK
http://java.sun.com/
44
Tools
• IDE integration
• Eclipse plugin
• IntelliJ 8 built in support
• NetBeans
45
Tools
• Grails Console
• run Groovy Scripts
• test Domain classes
46
Tools
• Grails Shell
• create scripts
• domain, controller,
view
• create and run tests
• unit tests
• integration test
• deploy application
• start server
Grails Features
48
Grails Features
• Model
• Application Flow
• Presentation
• Scaffolding
• Testing
• Plug-Ins
49
Model
• GORM
• Domain classes
• Basic CRUD
• Finders
50
GORM (Grails ORM)
• Simplifies data access
• Uses Groovy’s dynamic typing
• Injects CRUD methods into the domain class
• Provides dynamic finder methods
• Eliminates boiler plate code implementation
• No required inheritance from a persistent class
• Based on Hibernate 3
51
Basic Domain Creation
• Create a new domain class
app-dir> grails create-domain-class speaker
class Speaker {
static constraints = {
}
}
52
Basic Domain Creation
• Customize class
class Speaker {
String firstName
String lastName
String company
String title
static constraints = {
firstName(maxSize: 20)
lastName(maxSize:20)
title(maxSize:50)
}
}
optimistic locking
53
Basic CRUD
def spkr = new Speaker(firstName: ”Jhon”,
lastName: “Smith”, title: “Consultant”)
spkr.save()
Create
def spkr = Speaker.get(id)Read
def spkr = Speaker.get(id)
spkr.title = “Architect”
spkr.save()
Update
def spkr = Speaker.get(id)
spkr.delete()
Delete
54
Dynamic Finders
• Looks like a static method invocation
• methods do not exist in the code
• generated at runtime based on class properties
def spkr = Speaker.findByFirstName(“Jhon”)
def spkr = Speaker.findByFirstNameAndLastName(“Jhon”, “Smith”)
def spkrs = Speaker.findByAllFirstNameLike(“J%”)
def spkrs =
Book.findAllByTitleLike(“J%",
[max:3, offset:2, sort:"title", order:"desc"])
55
Application Flow
• Controllers
• Models and Views
• Data Binding
56
Controllers
• Handles requests
• Creates or prepares the response
• A new instance created for each request
• Default URL Mapping:
/app-name/speaker/update/id
applicationname
controller name
actionname
params.id
57
Controller Creation
• Create a new controller
app-dir> grails create-controller speaker
class SpeakerController {
def index = { }
def actionName = {
// do controller logic
// create model
return model
}
def defaultAction = “actionName"
}
58
Models and Views
• Returning the model
• a model is a map used by view to render
response
class BookController {
def show = {
[ book : Book.get( params.id ) ]
}
Explicit model map return
class BookController {
List books
List authors
def list = {
books = Book.list()
authors = Author.list()
}
}
Controller properties used as model
59
Models and Views
• Selecting the View
• implicit using conventions
• explicit using render
class BookController {
def show = {
[ book : Book.get( params.id ) ]
}
}
/app-name/views/book/show.gsp
Implicit
class BookController {
def show = {
def map = [ book : Book.get( params.id ) ]
render(view:"display", model:map)
}
/app-name/views/book/display.gsp
Explicit
60
Data Binding
• Binding Request Data to the Model
• Based on Spring’s binding
/book/save?book.title=The_Stand&author.name=Stephen_King
class BookController {
def save = {
def b = new Book(params[„book‟]) //implicit constructor
def a = new Author(params[„author‟]) //implicit constructor
a.addToBooks(b)
a.save()
}
def update = {
def b = Book.get(params.id)
b.properties = params
b.save()
}
}
61
Presentation
• GSP
• Grails Tags
• Templates
• Layouts
62
GSP (Grails Server Pages)
• Similar to JSP and ASP
• A mix of markup and GSP tags
• Uses model passed from Controller to render view
• GSP pages reside in “/grails-app/views” directory
• Supports scripting of Groovy (discouraged)
• Supports GSP expressions within “${ }”
63
GSP Tags
• Built-in GSP tags
• start with g: prefix (no tag library imports)
• attributes can be expression or maps
• control flow operations like in JSTL
• Tags as method calls
• GSP tags can be called as methods from
controllers, tag libraries or GSP views
<img src="<g:resource dir="images" file="logo.jpg" />" />
<img src="${resource(dir:'images', file:'logo.jpg')}" />
def imageLocation = g.resource(dir:"images", file:"logo.jpg")
64
Templates
• By convention _<view name> is a template
• can be rendered from a view or controller
<div class="book" id="${book?.id}">
<div>Title: ${book?.title}</div>
<div>Author: ${book?.author?.name}</div>
</div>
grails-app/views/book/_bookTemplate.gsp
<g:render template="bookTemplate" model="[book:myBook]" />
<g:render template="bookTemplate" var="book“
collection="${bookList}" />
grails-app/views/book/list.gsp
65
Layouts
• Based on Sitemesh
• a web-page layout and decoration framework
• decorates response and applies a consistent L&F
• uses composite pattern
• Layouts are located in grails-app/views/layouts
grails-app/views/layouts/customer.gsp
class BookController {
static layout = 'customer'
}
Specifying a Layout in a Controller
66
Services
• A class that ends with the convention “Service”
• Re-use business logic across application
• Controllers should handle request flow and redirects
• Manages transaction demarcation
app-dir> grails create-service simple
class SimpleService {
boolean transactional = true
def serviceMethod() {
}
}
67
Dependency Injection
• Use the property name representation of a service to
inject it to a Controller / Domain class
• Based on Spring Framework's dependency injection
capability
class BookController {
def bookService //BookService
…
}
class Book {
…
def bookService //BookService
def buyBook() {
bookService.buyBook(this)
}
}
68
Scaffolding
• auto-generate a whole application for a given domain
class including
• GSP views
• Controller actions for CRUD operations
• Database schema
• uses introspection
• dynamic scaffolding is generated at runtime
• static scaffolding is generated in source code
class BookController {
def scaffold = true
}
69
Testing
• Unit tests
• Grails does not inject dynamic methods
• no DB support
• based on JUnit
• extends GrailsUnitTestCase
• provides mocking support (EasyMock): mock*()
• uses assert*()
app-dir> grails create-unit-test speaker
app-dir> grails test-app -unit speaker
70
Testing
• Integration tests
• executes inside a full Grails environment
• runs against a live database
• uses Mock versions of the servlet request,
response, and session
• transaction is rolled back at the end
• supports URL mappings
app-dir> grails create-integration-test speaker
app-dir> grails test-app speaker
71
Plug-ins
• Core plugins• GORM, Controllers, WebFlow, etc.
• Custom plugins
• Grails Plugin Repository
• http://grails.org/plugin/home
• per project / global
app-dir> grails list-plugins
app-dir> grails install-plugin <plugin-name>
72
Performance
• The bad
• Dynamic is slower than static
• Many abstraction layers
• The good
• Bottleneck is usually I/O not CPU
• JDK 7 (JSR 292)
• OpenJDK: Da Vinci Project
Google App Engine
Start your engine …
74
Google App Engine
• A platform for developing and hosting
web applications in Google-managed
data centers
• Virtualizes applications across multiple
servers and data centers (cloud computing)
2007 20092008
1.0 Release 1.2.7 Releasebeta
75
Google App Engine
• Free up to a certain level of resources
• Fees are charged for additional storage,
bandwidth, CPU
• Supports: Python and JVM languages
(Java, Groovy, JRuby, Scala, Clojure)
76
Grails on AppEngine
• Groovy 1.6.1 runs on AppEngine
• Grails 1.1.1 adds official support
• Grails AppEngine Plugin
• Replaces Hibernate with JDO (soon JPA)
• Integrates with AppEngine dev environment
and deployment tools
77
• Grails• http://www.grails.org/Documentation
• http://old.nabble.com/grails---user-f11861.html
• Groovy• http://groovy.codehaus.org/
• http://groovymag.com/
• Google App Engine• http://code.google.com/appengine/
• http://grails.org/plugin/app-engine
• http://groups.google.com/group/google-appengine-
java/web/will-it-play-in-app-engine?pli=1
References
78
Documentation
• Internet• http://grails.org/Documentation
• Books
• 9 books on Amazon!