2007 09 10 Fzi Training Groovy Grails V Ws

67 %
33 %
Information about 2007 09 10 Fzi Training Groovy Grails V Ws

Published on September 8, 2007

Author: loffenauer

Source: slideshare.net

Description

2-3 hour introduction to GROOVY and GRAILS given on Sep 10, 2007 for an internal tech talk at the FZI, Germany

Groovy & Grails Lightning Talk Raphael Volz Sep. 10, 2007 FZI, Karlsruhe Builds on content from the following presentations Rod Cope and James Strachan The Groovy Programming Language Presentation held at JavaOne 2004 Graeme Rocher Rapid Web Application Development with Grails Presentation held at JavaOne 2006

Builds on content from the following presentations

Rod Cope and James Strachan The Groovy Programming Language Presentation held at JavaOne 2004

Graeme Rocher Rapid Web Application Development with Grails Presentation held at JavaOne 2006

Agenda Why should I care ? Get Groovy Find Grails

Why should I care ?

Get Groovy

Find Grails

Why should I care ? 40-60% User Interface 40-60% Functionality Software Development Effort Variance Max. 20 % User Interface Min. 80% Functionality Focus : Users  Great Interface  Developer  Gigantic Functionality Typically Research … try to be efficient in programming efforts … ... try to be efficient in UI efforts...

Efficiency Problems in Web Development Many repetitive tasks Consider example data flow: Database – Object Representation – Presentation HTML Different structure of individual applications Hard to understand Hard to maintain Difficulty to get started Many concepts at once: HTML, XML, SQL, JavaScript, Programming Languages … Need: Simplification Standardization Capture “Best Practices”

Many repetitive tasks

Consider example data flow: Database – Object Representation – Presentation HTML

Different structure of individual applications

Hard to understand

Hard to maintain

Difficulty to get started

Many concepts at once: HTML, XML, SQL, JavaScript, Programming Languages …

Need:

Simplification

Standardization

Capture “Best Practices”

Java’s biggest strengths in Web development ? VM and Binary Compatibility We can build deployment units (class, jar, jnlp, war, ear, rar, car) and run them anywhere We can easily reuse libraries, APIs and tools e.g. high quality BPM, SemWeb, Market APIs Lots of reusable software & components & tools We can innovate at the source code level if we play nice at the binary level

VM and Binary Compatibility

We can build deployment units (class, jar, jnlp, war, ear, rar, car) and run them anywhere

We can easily reuse libraries, APIs and tools

e.g. high quality BPM, SemWeb, Market APIs

Lots of reusable software & components & tools

We can innovate at the source code level if we play nice at the binary level

Problems with Java in Web Dev’t Verbose Many import statements Try… Catch Nightmare … Static Compile Cycle prevents necessary agility Language Concepts (in my opinion) slow to embrace “modern” concepts … … many of which are helpful for Web Development

Verbose

Many import statements

Try… Catch Nightmare



Static

Compile Cycle prevents necessary agility

Language Concepts

(in my opinion) slow to embrace “modern” concepts …

… many of which are helpful for Web Development

Agenda Why should I care ? Get Groovy Find Grails

Why should I care ?

Get Groovy

Find Grails

Get Groovy – An agile dynamic language for Java Integrates with Java Can call Java Can be called by Java Compiles to Java byte code Simplifies syntax of java Adds modern language features from Python, Ruby, Dylan and Smalltalk to Java Supports DSL (domain specific languages) to compact syntax and increase readability Reduces scaffolding code (Web, GUI, database) Simplifies testing (mocks up out-of-the-box)

Integrates with Java

Can call Java

Can be called by Java

Compiles to Java byte code

Simplifies syntax of java

Adds modern language features from Python, Ruby, Dylan and Smalltalk to Java

Supports DSL (domain specific languages) to compact syntax and increase readability

Reduces scaffolding code (Web, GUI, database)

Simplifies testing (mocks up out-of-the-box)

Groovy // Simplifying Java Syntax (1) Automatically imports groovy.lang.* groovy.util.* java.lang.* java.util.* java.net.* java.io.* java.math.BigInteger java.math.BigDecimal Declare all imports Imports PUBLIC PRIVATE Default scope OPTIONAL MUST Typing of variables OPTIONAL MUST Brackets with method calls OPTIONAL MUST Semicolon after statement Groovy Java Feature

Automatically imports

groovy.lang.*

groovy.util.*

java.lang.*

java.util.*

java.net.*

java.io.*

java.math.BigInteger

java.math.BigDecimal

Groovy // New features beyond Java Everything is an object Groovy Beans Automatically generates get/set methods Uses these methods when attributes are read Simple Notation of lists and (hash) maps Closures - Objects with executable code Operator overloading Extended Switch

Everything is an object

Groovy Beans

Automatically generates get/set methods

Uses these methods when attributes are read

Simple Notation of lists and (hash) maps

Closures - Objects with executable code

Operator overloading

Extended Switch

Groovy // Hello World Java public class HelloWorld { public static void main (String[] args) { System.out.println( “Hello World”); } } Groovy println “Hello World” Simplifications applied Public optional Type information optional Every Class knows “println” Script needs no class and main method context Semicolon optional Brackets are optional when calling methods Println “Hello World” class HelloWorld { static void main (String[] args) { System.out.println( “Hello World”); } } class HelloWorld { static main (args) { System.out.println( “Hello World”); } } class HelloWorld { static main (args) { println(“Hello World”); } } println(“Hello World”); Println “Hello World”

Java

public class HelloWorld {

public static void main (String[] args) {

System.out.println( “Hello World”);

}

}

Groovy

println “Hello World”

Simplifications applied

Public optional

Type information optional

Every Class knows “println”

Script needs no class and main method context

Semicolon optional

Brackets are optional when calling methods

Groovy // Closures : Blocks of code as objects def c = { println "hello" } c() square = { x -> x * x } assert square(2) == 4 square = { it * it } 3.times { println "hoch!" } def sum = 0 1.upto(5) { sum += it } assert sum == 15 Use to substitute repeated code blocks Closure with parameter Closure with default parameter "it" does not require return Times function upto function Remember LISP ? ... pass around as references, store, execute at arbitratry time ... similar to anonymous inner classes, but nicer syntax and more flexible

def c = { println "hello" } c()

square = { x -> x * x } assert square(2) == 4

square = { it * it }

3.times { println "hoch!" }

def sum = 0 1.upto(5) { sum += it } assert sum == 15

Use to substitute repeated code blocks

Closure with parameter

Closure with default parameter "it" does not require return

Times function

upto function

Groovy // Calling Java APIS 10 liner to get "Google Patent Search" results via HTMLUnit 1 import com.gargoylesoftware.htmlunit.WebClient 2 def searchTerm = 'Robot' // Patent Search with Google 3 def client = new WebClient() 4 def page = client.getPage('http://www.google.com/patents') 5 def input = page.forms[0].getInputByName('q') 6 input.valueAttribute = searchTerm 7 page = page.forms[0].submit() 8 def results = page.anchors.grep { it.classAttribute == 'big' } 9 results.each { 10 println it.hrefAttribute.padRight(30) + ' : ' + it.asText() } Closure

10 liner to get "Google Patent Search" results via HTMLUnit

1 import com.gargoylesoftware.htmlunit.WebClient

2 def searchTerm = 'Robot'

// Patent Search with Google

3 def client = new WebClient()

4 def page = client.getPage('http://www.google.com/patents')

5 def input = page.forms[0].getInputByName('q')

6 input.valueAttribute = searchTerm

7 page = page.forms[0].submit()

8 def results = page.anchors.grep { it.classAttribute == 'big' }

9 results.each {

10 println it.hrefAttribute.padRight(30) + ' : ' + it.asText() }

Groovy // Everything is an object def i = 1 assert i == new Integer (1) def k = i assert i.is(k) assert !(i.is(new Integer(i))) No primitive datatypes Int, short byte, long real objects == is equals() Checks equality of objects is() checks identity of objects Very, very useful when writing test code !!!

def i = 1

assert i == new Integer (1)

def k = i assert i.is(k) assert !(i.is(new Integer(i)))

No primitive datatypes

Int, short byte, long real objects

== is equals()

Checks equality of objects

is() checks identity of objects

Groovy // Groovy Beans vs. Java Beans Java public class Person { private String firstName; private String nickName; public String getFirstName() { return firstName; } public String setFirstName( String n) { this.name = n; } ... } Person p = new Person(); p.setFirstName("Raphael"); System.out.println(p.getName()); Groovy class Person { String firstName; String nickName String getNickName() { if (!nickName) return firstName else return nickname } } def p = new Person(firstName: 'Raphael' ) assert p.nickName == 'Raphael'

Java

public class Person {

private String firstName;

private String nickName;

public String getFirstName() {

return firstName;

}

public String setFirstName( String n) {

this.name = n;

}

...

}

Person p = new Person();

p.setFirstName("Raphael");

System.out.println(p.getName());

Groovy

class Person {

String firstName;

String nickName

String getNickName() {

if (!nickName) return firstName else return nickname

}

}

def p = new Person(firstName: 'Raphael' )

assert p.nickName == 'Raphael'

Groovy // Simplified List Handling def list = [1,2,3] assert list[0] == 1 assert list[-1] == 3 assert list[1..2] == [2,3] assert list + [4,5] == [1,2,3,4,5] assert list << 9 == [1,2,3,9] assert [1,2,3] - [2] == [1,3] assert [1,2] * 2 == [1,2,1,2] def sum = 0 for (i in list) sum+= i asset sum == 6 Simplified addressing of list elements avoids calls to len() Simplied modification of lists Simplified iteration

def list = [1,2,3] assert list[0] == 1 assert list[-1] == 3 assert list[1..2] == [2,3]

assert list + [4,5] == [1,2,3,4,5] assert list << 9 == [1,2,3,9]

assert [1,2,3] - [2] == [1,3] assert [1,2] * 2 == [1,2,1,2]

def sum = 0 for (i in list) sum+= i asset sum == 6

Simplified addressing of list elements avoids calls to len()

Simplied modification of lists

Simplified iteration

Groovy // List Handling Example public class Filter { public static void main( String[] args ) { List list = new java.util.ArrayList(); list.add( &quot;Rod&quot; ); list.add( &quot;James&quot; ); list.add( &quot;Chris&quot; ); Filter filter = new Filter(); List shorts = filter.filterLongerThan( list, 4 ) for ( String item : shorts ) { System.out.println( item ); } } public List filterLongerThan( List list, int length ) { List result = new ArrayList(); for ( String item : list ) { if ( item.length() <= length ) { result.add( item ); } } return result; } } Select all names with at most 3 characters from a list Groovy Java list = [&quot;Rod&quot;, &quot;James&quot;, &quot;Chris&quot;] shorts = list.findAll { it.size() <= 4 } shorts.each { println it }

public class Filter {

public static void main( String[] args ) {

List list = new java.util.ArrayList();

list.add( &quot;Rod&quot; ); list.add( &quot;James&quot; ); list.add( &quot;Chris&quot; );

Filter filter = new Filter();

List shorts = filter.filterLongerThan( list, 4 )

for ( String item : shorts ) { System.out.println( item ); }

}

public List filterLongerThan( List list, int length ) {

List result = new ArrayList();

for ( String item : list ) {

if ( item.length() <= length ) { result.add( item ); }

}

return result;

}

}

Groovy // Ranges and Maps def sum = 0 for (i in 1..10) sum += i assert sum ==55 map = ['rod' : 33, 'james' : 35] assert map['rod'] == map.rod map.joe = 28 assert map == ['rod':33, 'james':35, 'joe':28] assert map.subMap(['rod', 'joe']) == ['rod':33, 'joe':28]

def sum = 0 for (i in 1..10) sum += i assert sum ==55

map = ['rod' : 33, 'james' : 35] assert map['rod'] == map.rod

map.joe = 28 assert map == ['rod':33, 'james':35, 'joe':28]

assert map.subMap(['rod', 'joe']) == ['rod':33, 'joe':28]

Basic Sorting list = [ 'dog', 'bird', 'chick' ] println( list.sort() ) -> [bird, chick, dog] println( list.sort { it.size() }.reverse() ) -> [chick, bird, dog]

list = [ 'dog', 'bird', 'chick' ]

println( list.sort() )

-> [bird, chick, dog]

println( list.sort { it.size() }.reverse() )

-> [chick, bird, dog]

Sorting JavaBeans class Person { name; age } list = [ new Person( name:'Rod', age:33 ), new Person( name:'James', age:35 ) ] list.sort { | person | person.age } list.sort { [ it.name, it.age ] } list.sort { | a, b | a.name <=> b.name } println( list.sort{it.name}.name ) -> [James, Rod] println(list.sort{it.name}.name.join(':')) -> &quot;James:Rod&quot;

class Person { name; age }

list = [ new Person( name:'Rod', age:33 ),

new Person( name:'James', age:35 ) ]

list.sort { | person | person.age }

list.sort { [ it.name, it.age ] }

list.sort { | a, b | a.name <=> b.name }

println( list.sort{it.name}.name )

-> [James, Rod]

println(list.sort{it.name}.name.join(':'))

-> &quot;James:Rod&quot;

Groovy // Operator Overloading Maps Operators to Methods Can be implemented by any class and subsequently used Operator Name Method a+b plus a.plus(b) a-b minus a.minus(b) a*b star a.multiply(b) a/b divide a.div(b) a % b modulo a.mod(b) a++ increment a.next() a-- decrement a.previous() a**b power a.power(b)

Maps Operators to Methods

Can be implemented by any class and subsequently used

Operator Name Method a+b plus a.plus(b) a-b minus a.minus(b) a*b star a.multiply(b) a/b divide a.div(b) a % b modulo a.mod(b) a++ increment a.next() a-- decrement a.previous() a**b power a.power(b)

Groovy // Advanced switch switch (v) { case 1: println 'Number one'; break; case 'test': println 'String test'; break; case 2..15 : println 'in range 2 to 15'; break; case [1, '1', 'One'] : println 'Number one'; break; case ~/A.*/: println 'Starts with A'; break; default: println 'Default Output'; break }

switch (v) { case 1: println 'Number one'; break; case 'test': println 'String test'; break; case 2..15 : println 'in range 2 to 15'; break; case [1, '1', 'One'] : println 'Number one'; break; case ~/A.*/: println 'Starts with A'; break; default: println 'Default Output'; break }

Groovy // Additional Library Adds methods missing from the JDK String contains(), count(), execute(), padLeft(), center(), padRight(), reverse(), tokenize(), each(), etc. Collection count(), collect(), join(), each(), reverseEach(), find/All(), min(), max(), inject(), sort(), etc. File eachFile(), eachLine(), withPrintWriter(), write(), getText(), etc.

Adds methods missing from the JDK

String

contains(), count(), execute(), padLeft(), center(), padRight(), reverse(), tokenize(), each(), etc.

Collection

count(), collect(), join(), each(), reverseEach(), find/All(), min(), max(), inject(), sort(), etc.

File

eachFile(), eachLine(), withPrintWriter(), write(), getText(), etc.

Groovy // Strings and Regular Expressions def cal = new GregorianCalendar() println &quot;Date: $cal.time&quot; assert 'only letters' ==~ /((w*) *)*/ assert 'only letters' =~ /w*/ def matcher = 'only letters' =~ /w*/ mather.each { println it } Usage of variables in strings Matches whole words Matches all words Print all words

def cal = new GregorianCalendar() println &quot;Date: $cal.time&quot;

assert 'only letters' ==~ /((w*) *)*/

assert 'only letters' =~ /w*/

def matcher = 'only letters' =~ /w*/ mather.each { println it }

Usage of variables in strings

Matches whole words

Matches all words

Print all words

Groovy // GPath path expressions class Person { name; age } list = [ new Person( name:'Rod', age:33 ), new Person( name:'James', age:35 ) ] println( list.find {it.age > 25}.name ) -> [Rod] println( list.findAll {it.age > 25}.name ) -> [Rod, James] println( list.any{ it.name.size() > 4 } ) -> true

class Person { name; age }

list = [ new Person( name:'Rod', age:33 ),

new Person( name:'James', age:35 ) ]

println( list.find {it.age > 25}.name )

-> [Rod]

println( list.findAll {it.age > 25}.name )

-> [Rod, James]

println( list.any{ it.name.size() > 4 } )

-> true

Groovy // Builders Implemenation of Builder Design Pattern Used to construct other things Groovy provides builders for Groovy objects NodeBuilder XML,HTML groovy.xml.MarkupBuilder Swing SwingBuilder Ant AntBuilder Can add own Builders (very powerful) Who writes one for RDF ? Who writes one for OWL ? Who writes one for BPEL ?

Implemenation of Builder Design Pattern

Used to construct other things

Groovy provides builders for

Groovy objects NodeBuilder

XML,HTML groovy.xml.MarkupBuilder

Swing SwingBuilder

Ant AntBuilder

Can add own Builders (very powerful)

Who writes one for RDF ?

Who writes one for OWL ?

Who writes one for BPEL ?

Groovy // XML Builder Groovy data = ['Rod': ['Misha':8, 'Bowie':2], 'Eric': ['Poe':4, 'Doc':3] ] xml = new groovy.xml.MarkupBuilder() people = xml.people() { for ( entry in data ) { person( name: entry.key ) { for ( dog in entry.value) { pet( name:dog.key, age:dog.value ) } } } } XML <people> <person name='Rod'> <pet name='Bowie' age='2' /> <pet name='Misha' age='8' /> </person> <person name='Eric'> <pet name='Poe' age='4' /> <pet name='Doc' age='3' /> </person> </people>

Groovy

data = ['Rod': ['Misha':8, 'Bowie':2], 'Eric': ['Poe':4, 'Doc':3] ]

xml = new groovy.xml.MarkupBuilder()

people = xml.people() {

for ( entry in data ) { person( name: entry.key ) { for ( dog in entry.value) { pet( name:dog.key, age:dog.value ) } }

}

}

XML

<people>

<person name='Rod'>

<pet name='Bowie' age='2' />

<pet name='Misha' age='8' />

</person>

<person name='Eric'>

<pet name='Poe' age='4' />

<pet name='Doc' age='3' />

</person>

</people>

Groovy // XML Parser XML <people> <person name='Rod'> <pet name='Bowie' age='2' /> <pet name='Misha' age='8' /> </person> <person name='Eric'> <pet name='Poe' age='4' /> <pet name='Doc' age='3' /> </person> </people> Groovy def persons = new XmlParser(). parseText(text); assert people.person.pet.name == ['Bowie', 'Misha', 'Poe', 'Doc']

XML

<people>

<person name='Rod'>

<pet name='Bowie' age='2' />

<pet name='Misha' age='8' />

</person>

<person name='Eric'>

<pet name='Poe' age='4' />

<pet name='Doc' age='3' />

</person>

</people>

Groovy

def persons = new XmlParser(). parseText(text);

assert people.person.pet.name == ['Bowie', 'Misha', 'Poe', 'Doc']

Groovy // Dynamic Features Meta Object protocol Intercept method calls Control access to properties Control access to classes Expando Object def e = new Expando () e.a = Math.PI e.m = { println 'I am an expando, this is new method m' } e.m() Duck Typing class Fish { def swim() { println 'I am a fish' } } class Dolphin {def swim() { println 'I am a dolphin' } } [new Fish(), new Dolphin()].each { it.swim() }

Meta Object protocol

Intercept method calls

Control access to properties

Control access to classes

Expando Object

def e = new Expando () e.a = Math.PI e.m = { println 'I am an expando, this is new method m' } e.m()

Duck Typing

class Fish { def swim() { println 'I am a fish' } } class Dolphin {def swim() { println 'I am a dolphin' } } [new Fish(), new Dolphin()].each { it.swim() }

Groovy // Summary Groovy Dynamic, flexible Components Focus Adaptivity, Prototyping Java Static, stable Components Critical for runtime More efficient compiler Typically 50% less development effort (*) Note: (*) Comes at higher debugging expense and 20-90% performance

Groovy

Dynamic, flexible Components

Focus Adaptivity, Prototyping

Java

Static, stable Components

Critical for runtime

More efficient compiler

Agenda Why should I care ? Get Groovy Find Grails

Why should I care ?

Get Groovy

Find Grails

What is GRAILS ? Grails is an MVC Web framework Initially inspired by Ruby on Rails Built upon solid bricks & best of breed components Spring : IoC, DI, Spring MVC, transactional support, experimental Spring WebFlow… Hibernate : ORM, querying mechanism… Groovy : for focusing on everything that matters And: SiteMesh, Quarz, AJAX frameworks… « Convention over configuration »: Focus not on wiring and configuration!

Grails is an MVC Web framework

Initially inspired by Ruby on Rails

Built upon solid bricks & best of breed components

Spring : IoC, DI, Spring MVC, transactional support, experimental Spring WebFlow…

Hibernate : ORM, querying mechanism…

Groovy : for focusing on everything that matters

And: SiteMesh, Quarz, AJAX frameworks…

« Convention over configuration »: Focus not on wiring and configuration!

GRAILS // Layering on Java Components Source: G. K. Rocher, The Definite Guide to Grails, Apress, 2006, p. 7

GRAILS // Step 1

Source: G. K. Rocher, The Definite Guide to Grails, Apress, 2006, p. 39

GRAILS // Basic application already there after Step 1

GRAILS // Step 2 - Define a Model • Now that the skeleton is there, focus on the model • Model backed by GORM • The model is just a set POGO s (Plain Old Groovy Objects) • First class of our domain: the books class Book { String title String author String publisher }

• Now that the skeleton is there, focus on the model

• Model backed by GORM

• The model is just a set POGO s

(Plain Old Groovy Objects)

• First class of our domain: the books

class Book {

String title

String author

String publisher

}

GRAILS // GRAILS Contribution • Automatically, Grails add dynamic instance & static methods to all your domain classes: Static methods: Instance methods: • Book.get(1) • Book.save() • Book.find() • book.validate() • Book.findAll() • book.update() • bok.delete()

• Automatically, Grails add dynamic instance &

static

methods to all your domain classes:

Static methods: Instance methods:

• Book.get(1) • Book.save()

• Book.find() • book.validate()

• Book.findAll() • book.update()

• bok.delete()

GRAILS // Step 3 Generation of views and controllers • Once the Book class is created, let´s benefint from static scaffolding -> grails generate-all -> grails run-app • A BookController is created, as well as four GSP: ▪ create.gsp ▪ edit.gsp ▪ list.gsp ▪ show.gsp

GRAILS // Scaffolding provides basic GUI for CRUD

GRAILS // Taking control of GRAILS V iew M odel C ontroller grails generate-controller /grails-app/controllers grails generate-views /grails-app/views grails create-domain-class /grails-app/model J obs S ervices /grails-app/jobs /grails-app/services grails create-app 1 2 Web Test Unit Test 4 5 6 grails generate-all 3

GRAILS // VIEW CONTROLLER INTERACTION Source: G. K. Rocher, The Definite Guide to Grails, Apress, 2006

GRAILS // Hibernate interaction • Hibernate is the de facto ORM solution • Domain classes are automatically and transparently mapped with Hibernate • 1:1, 1:n & m:n realtionships supported • Various database environments (dev, test, prod) • Default HSQLDB in-memory config • You can even provide your own Hibernate mapping files for legacy schemas • You can also reuse your EJB3 ! V M C S J

GRAILS // A more complex domain class Author { String firstName String lastName def hasMany = [books: Book ] String toString() { “ $firstName $lastName” } } class Book { String title Author author Publisher publisher def belongsTo = [ Publisher , Author ] String toString() { title } } class Publisher { String name def hasMany = [ books: Book ] String toString() { name } } Author has many Books Publisher has many Books V M C S J

GRAILS // Domain with constraints to keep valid Add an email to Author class Author { String email // … static constraints = { email (email: true) } } Add an ISBN to Book class Book { Stringisbn // … static constraints = { isbn (matches: “ [0-9] {9} [0-9X ]”) } } V M C S J

GRAILS // ... and even more constraints • Many constraints available: blank , creditcard, email, inList , length, min, minLength, minSize, matches , max, maxLength, maxSize, notEqual, nullable , range , size, unique , url , validator • And you can create your own closure validator: even( validator: { it % 2 == 0 )} V M C S J

GRAILS // Querying your Model Grails provides various querying mechanisms: Dynamic finder methods Query by example Criteria builders Full-blown HQL queries V M C S J

Grails provides various querying mechanisms:

Dynamic finder methods

Query by example

Criteria builders

Full-blown HQL queries

GRAILS // Query Examples • Book. find By Title (“The Stand”) Book.findByTitle Like (“Harry Pot%”) Book.findByReleaseData Between (start, end) Book.findByTitleLike Or ReleaseData LessThan ( “ %Grails%”, someData) • Find by relationship Book.find All By Author ( Author.get(1) ) • Affect sorting Book.findAllbyAuthor(me, [sort:‘title’,order:’asc’] ) V M C S J

GRAILS // Views • Spring MVC under the hood • Support for flash scope between requests • GSP : Groovy alternative to JSP • Dynamic taglib development: no TLD, no configuration, just conventions • Adaptive AJAX tags (Yahoo, Dojo, Prototype) • Customizable layout with SiteMesh • Page fragments through reusable templates • View under grails-app/views V M C S J TIP: Use grails install-templates to install and customize your the templates to be used for generation (templates in ../src/templates)

GRAILS // GSP Groovy Server Pages <html> <head> <meta name=“layout“ content=“main“ /> <title>Book List</title> </head> <body> <a href=“ $ {createLinkTo(dir:’’)} ”>Home</a> <g:link action=“create”> New Book</g:link> <g:if test=“ $ { flash.message } ”> ${flash.message} </g:if> <g:each in=“${bookList}”> $ {it.title} </g:each> </body> </html> V M C S J

GRAILS // Rich Set of Dynamic Tag Libs • Logical: if, else, elseif • Iterative: while, each, collect, findAll… • Linking: link, createLink, createLinkTo • Ajax: remoteFunction, remoteLink, formRemote, submitToRemote… • Form: form, select, currencySelect, localSelect, datePicker, checkBox… • Rendering: render*, layout*, paginate… • Validation: eachError, hasError, message • UI: rich TextEditor… V M C S J

GRAILS // URL Convention • URL mapping convention: controller/action/id http://localhost:8080/library/ book / show / 1 • Scaffolding can be ▪ dynamic (def scaffold = true) ▪ static (code generation) • Controllers pass data to the view through maps • Direct access to parameters • Easy redirect and forward • Can define allowed methods for each action V M C S J

GRAILS // Controllers provide actions to execute (call) class Book Controller { def index = { redirect(action:list,params:params) } def list = { [ bookList: Book.list( params )] } def show = { [ book : Book.get( params.id ) ] } def edit = { def book = Book.get( params.id ) if(!book) { flash.message = “Book ${params.id} not found” redirect(action:list) } else return [ book : book ] } } V M C S J

GRAILS // Chaining and Flashing Source: G. K. Rocher, The Definite Guide to Grails, Apress, 2006

GRAILS // Services • Services are Groovy classes that should contain your business logic • Automatic injection of services in controllers & services simply by declaring a field: class BookController { MySuperService mySuperService } V M C S J

Grails // Jobs • You can create recuring events with Quartz under the hood, configured by Spring • Again a convention on the name and directory • Regular intervals, or cron definitions • class My Job {} def cronExpression = “0 0 24 * * ?” def execute() { print “Job run!” } } V M C S J

Further Reading

Concluding Notes Slides (largely) inspired by the following two presentations Rod Cope and James Strachan The Groovy Programming Language Presentation held at JavaOne 2004 Graeme Rocher Rapid Web Application Development with Grails Presentation held at JavaOne 2006 Get started with... GRAILS: grails.codehaus.org GROOVY: groovy.codehaus.org

Slides (largely) inspired by the following two presentations

Rod Cope and James Strachan The Groovy Programming Language Presentation held at JavaOne 2004

Graeme Rocher Rapid Web Application Development with Grails Presentation held at JavaOne 2006

Get started with...

GRAILS: grails.codehaus.org

GROOVY: groovy.codehaus.org

Add a comment

Related presentations

Related pages

Tutorial: Grails, Plugins und praktische Java-Bibliotheken

Kategorien: Java, Groovy & Grails. 2 Feedbacks ... (siehe http://www.slideshare.net/loffenauer/2007-09-10-fzi-training-groovy-grails-v-ws) ...
Read more

Groovy / Grails | LinkedIn

View 6417 Groovy / Grails ... candidates who are 10 ... Training IPhone Training Android Training Titanium Certified Developer Training Groovy/Grails ...
Read more

Groovy/grails | LinkedIn

Hiring Groovy/Grails developer in Philadelphia, PA. Send your resumes to jenny@vdartinc.com Views 9 views. Title : Technical Lead Location: Philadelphia ...
Read more

Grails Talk and Demo by Sven Haiges at Google

2007 09 10 Fzi Training Groovy Grails V Ws... 2007 for an internal tech talk at the ... 09.03.2010 · Groovy/Grails Talk Bill Turner’s Groovy/Grails blog ...
Read more

The Grails Framework

... opinionated APIS and the Groovy language combine to make Grails easy to learn for ... Would you like to spend 2 days with 150+ Groovy & Grails ...
Read more