0
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 1
© Copyright 2010, Software Alchemy
Getting Gro...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 2
© Copyright 2010, Software Alchemy
Grails
Arch...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 3
© Copyright 2010, Software Alchemy
Install Gra...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 4
© Copyright 2010, Software Alchemy
Create a Gr...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 5
© Copyright 2010, Software Alchemy
MyApp Use C...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 6
© Copyright 2010, Software Alchemy
Create a Do...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 7
© Copyright 2010, Software Alchemy
Create a GU...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 8
© Copyright 2010, Software Alchemy
Default GUI...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 9
© Copyright 2010, Software Alchemy
Default GUI...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 10
© Copyright 2010, Software Alchemy
Default GU...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 11
© Copyright 2010, Software Alchemy
Behind the...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 12
© Copyright 2010, Software Alchemy
Behind the...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 13
© Copyright 2010, Software Alchemy
Behind the...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 14
© Copyright 2010, Software Alchemy
Behind the...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 15
© Copyright 2010, Software Alchemy
A Simple R...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 16
© Copyright 2010, Software Alchemy
Create GUI...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 17
© Copyright 2010, Software Alchemy
Fix Depart...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 18
© Copyright 2010, Software Alchemy
Grails
Arc...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 19
© Copyright 2010, Software Alchemy
Grails Tec...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 20
© Copyright 2010, Software Alchemy
Groovy Qui...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 21
© Copyright 2010, Software Alchemy
Groovy Qui...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 22
© Copyright 2010, Software Alchemy
Convention...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 23
© Copyright 2010, Software Alchemy
Logging
● ...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 24
© Copyright 2010, Software Alchemy
Data Sourc...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 25
© Copyright 2010, Software Alchemy
Example: M...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 26
© Copyright 2010, Software Alchemy
Pre-popula...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 27
© Copyright 2010, Software Alchemy
Eclipse In...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 28
© Copyright 2010, Software Alchemy
Maven Inte...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 29
© Copyright 2010, Software Alchemy
Ant Integr...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 30
© Copyright 2010, Software Alchemy
External D...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 31
© Copyright 2010, Software Alchemy
Web Techno...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 32
© Copyright 2010, Software Alchemy
Controller...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 33
© Copyright 2010, Software Alchemy
Views: GSP...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 34
© Copyright 2010, Software Alchemy
Tag Librar...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 35
© Copyright 2010, Software Alchemy
Request Fi...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 36
© Copyright 2010, Software Alchemy
Transactio...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 37
© Copyright 2010, Software Alchemy
Plugins
● ...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 38
© Copyright 2010, Software Alchemy
Spring Sec...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 39
© Copyright 2010, Software Alchemy
BootStrap ...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 40
© Copyright 2010, Software Alchemy
Define Sec...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 41
© Copyright 2010, Software Alchemy
Grails
Arc...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 42
© Copyright 2010, Software Alchemy
HrApp Use ...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 43
© Copyright 2010, Software Alchemy
Domain Mod...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 44
© Copyright 2010, Software Alchemy
Property V...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 45
© Copyright 2010, Software Alchemy
Basic Enum...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 46
© Copyright 2010, Software Alchemy
Enumerated...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 47
© Copyright 2010, Software Alchemy
Derived Pr...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 48
© Copyright 2010, Software Alchemy
Derived Re...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 49
© Copyright 2010, Software Alchemy
Embedded P...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 50
© Copyright 2010, Software Alchemy
Embedded P...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 51
© Copyright 2010, Software Alchemy
Relationsh...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 52
© Copyright 2010, Software Alchemy
One-to-One...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 53
© Copyright 2010, Software Alchemy
One-to-Man...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 54
© Copyright 2010, Software Alchemy
Inheritanc...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 55
© Copyright 2010, Software Alchemy
Inheritanc...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 56
© Copyright 2010, Software Alchemy
Inheritanc...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 57
© Copyright 2010, Software Alchemy
Grails
Arc...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 58
© Copyright 2010, Software Alchemy
Ten Great ...
Rochester JUG: 9-Nov-2010
Bryan Basham – Getting Groovy with Grails Slide 59
© Copyright 2010, Software Alchemy
Resources
...
Upcoming SlideShare
Loading in...5
×

Getting Groovy With Grails

595

Published on

Grails is an advanced web application development framework focused on rapid prototyping. It uses the Groovy language and runs on a standard JVM. This presentation will provide a hands-on introduction to using Grails and then provides examples of Grails applications. Grails is based upon a plugin architecture and several significant plugins will be described, such as the Spring Security plugin for web authentication and authorization.

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
595
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
23
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Transcript of "Getting Groovy With Grails"

  1. 1. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 1 © Copyright 2010, Software Alchemy Getting Groovy with Grails Bryan Basham Software Alchemy basham47@gmail.com http://www.linkedin.com/in/SoftwareAlchemist Grails Architecture Getting Groovy w/ Grails Domain Modeling Getting Started
  2. 2. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 2 © Copyright 2010, Software Alchemy Grails Architecture Domain Modeling Getting Groovy w/ Grails Install Grails Create App Create Entity GUI Scaffolding Basic Domain Modeling Getting Started Getting Started
  3. 3. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 3 © Copyright 2010, Software Alchemy Install Grails ● Download Grails at http://www.grails.org/ – I am using version 1.3.4 for this tech talk ● Unpack ZIP file on computer ● Set GRAILS_HOME environment variable ● Add $GRAILS_HOME/bin to PATH
  4. 4. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 4 © Copyright 2010, Software Alchemy Create a Grails App ● Execute command, eg: grails create-app MyApp
  5. 5. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 5 © Copyright 2010, Software Alchemy MyApp Use Cases List employees Update employee Create employee Retrieve employee Delete employee Classic CRUD Operations
  6. 6. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 6 © Copyright 2010, Software Alchemy Create a Domain Entity ● Create the Employee domain class, eg: grails create-domain-class com.example.Employee package com.example class Employee { String firstName String lastName Integer age static constraints = { } } «entity» Employee {from com.example} firstName : String lastName : String age : Integer
  7. 7. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 7 © Copyright 2010, Software Alchemy Create a GUI Controller ● Create the Employee controller class, eg: grails create-controller com.example.Employee package com.example class EmployeeController { def scaffold = Employee } ● Grails scaffolding provides all basic CRUD operations and GUI Views
  8. 8. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 8 © Copyright 2010, Software Alchemy Default GUI Scaffolding
  9. 9. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 9 © Copyright 2010, Software Alchemy Default GUI Scaffolding (2)
  10. 10. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 10 © Copyright 2010, Software Alchemy Default GUI Scaffolding (3)
  11. 11. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 11 © Copyright 2010, Software Alchemy Behind the Looking Glass ● Create the Employee GUI controller class: grails generate-controller com.example.Employee class EmployeeController { def index = { redirect(action: "list", params: params) } def list = { params.max = Math.min(params.max ? params.int('max') : 10, 100) [employeeList: Employee.list(params), employeeTotal: Employee.count()] } def save = { def employee = new Employee(params) if (employee.save(flush: true)) { flash.message = "Employee ${employee.id} created." redirect(action: "show", id: employee.id) } else { render(view: "create", model: [employeeInstance: employee]) } }
  12. 12. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 12 © Copyright 2010, Software Alchemy Behind the Looking Glass (2) ● Create the Employee GUI views: grails generate-views com.example.Employee
  13. 13. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 13 © Copyright 2010, Software Alchemy Behind the Looking Glass (3) ● The list.gsp View: <table> <tbody> <g:each in="${employeeList}" status="i" var="employee"> <tr class="${(i % 2) == 0 ? 'odd' : 'even'}"> <td><g:link action="show" id="${employee.id}"> ${fieldValue(bean: employee, field: "id")}</g:link> </td> <td>${fieldValue(bean: employee, field: "age")}</td> <td>${fieldValue(bean: employee, field: "firstName")}</td> <td>${fieldValue(bean: employee, field: "lastName")}</td> </tr> </g:each> </tbody> </table>
  14. 14. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 14 © Copyright 2010, Software Alchemy Behind the Looking Glass (4) ● The create.gsp View: <g:form action="save" > <table> <tbody> <tr class="prop"> <td valign="top" class="name"> <label for="age"><g:message code="employee.age.label" default="Age" /></label> </td> <td valign="top" class="value ${hasErrors(bean: employeeInstance, field: 'age', 'errors')}"> <g:textField name="age" value="${fieldValue(bean: employeeInstance, field: 'age')}" /> </td> </tr> ... </tbody> </table> </g:form>
  15. 15. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 15 © Copyright 2010, Software Alchemy A Simple Relationship class Employee { String firstName String lastName Integer age Department department static constraints = { } } «entity» Department {from com.example} name : String «entity» Employee {from com.example} firstName : String lastName : String age : Integer department 10..* class Department { String name static constraints = { } }
  16. 16. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 16 © Copyright 2010, Software Alchemy Create GUI components ● Create Department GUIs and recreate Employee GUIs A drop-down list of department objects, but the names are weird.
  17. 17. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 17 © Copyright 2010, Software Alchemy Fix Department Display ● Add a simple toString method: class Department { String name String toString() { name } static constraints = { } } The toString method is used to create a useful display name. You could also create custom GSP code for the drop-down list widget.
  18. 18. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 18 © Copyright 2010, Software Alchemy Grails Architecture Conv/Config Build tools Web techPlugins Groovy Getting Groovy w/ Grails Domain Modeling Install Grails Create App Create Entity GUI Scaffolding Basic Domain Modeling Getting Started Grails Architecture
  19. 19. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 19 © Copyright 2010, Software Alchemy Grails Technology Stack The Java Virtual Machine Groovy Java Lang / JRE JDK Grails JavaEE Spring Hibernate SiteMesh Plugins... Your Grails Application
  20. 20. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 20 © Copyright 2010, Software Alchemy Groovy Quick Look ● Groovy is a scripting langage on top of Java ● Syntax for lists and maps: – [1, 2, 3] – [foo:1, bar:2, baz:3] ● Closures: – [1, 2, 3].collect { it * it } => [1, 4, 9] ● Fancy Strings: – 'foo' is a Java String – “foo is ${map.foo}” is a GString
  21. 21. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 21 © Copyright 2010, Software Alchemy Groovy Quick Look (2) ● Groovy classes are JavaBeans class Employee { String name Integer age } ● Setter/Getters are auto created unless specified: class Employee { String name Date dateOfBirth Integer getAge() { /* calc age from DoB */ } }
  22. 22. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 22 © Copyright 2010, Software Alchemy Convention over Configuration ● Configuration is kept to a bare minimum ● Convention abounds: – Entities – Controllers and URL patterns – Services and dependency injection – Tag libraries – Scaffolding – and much more
  23. 23. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 23 © Copyright 2010, Software Alchemy Logging ● Configure logging in grails-app/conf/ Config.groovy file: log4j = { root { info 'stdout' additivity = true } info 'com.example' // more configuration snipped } ● Log objects automatically available: if (employeeInstance.save(flush: true)) { log.info "Employee ${employeeInstance.id} created." redirect(action: "show", id: employeeInstance.id) }
  24. 24. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 24 © Copyright 2010, Software Alchemy Data Sources ● Configured in the grails-app/conf/ DataSource.groovy file ● Database driver JAR file configured in the grails-app/conf/BuildConfig.groovy file ● Must create the database before using, but schema creation is handled by Grails – Use create-drop to create the DB on every run – This option destroys any data stored – Typically used during rapid prototyping
  25. 25. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 25 © Copyright 2010, Software Alchemy Example: MySQL ● DataSource.groovy: environments { development { dataSource { dbCreate = "create-drop" // one of 'create', 'create- drop','update' url = "jdbc:mysql://localhost:8889/my-app-db" driverClassName = "com.mysql.jdbc.Driver" username = "root" password = "root" } } ● BuildConfig.groovy: dependencies { runtime 'mysql:mysql-connector-java:5.1.12' }
  26. 26. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 26 © Copyright 2010, Software Alchemy Pre-populate DB ● Pre-populate the database using the grails- app/conf/BootStrap.groovy file: import com.example.Department; class BootStrap { def init = { servletContext -> if ( Department.count() == 0 ) { new Department(name:"Accounting").save() new Department(name:"Marketing").save() new Department(name:"Development").save() new Department(name:"Sales").save() } } def destroy = { } } The count() method is like the SQL statement: SELECT count(*) FROM department The save() method is like an SQL INSERT statement.
  27. 27. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 27 © Copyright 2010, Software Alchemy Eclipse Integration ● Install the Groovy plugin: http://dist.springsource.org/release/GRECLIPSE/e3.6/ ● Groovy support in Eclipse is spotty but workable – Hard to find all necessary libraries – No obvious access to source or javadocs – Debugging Grails apps is very difficult ● Maven helps with some of these issues
  28. 28. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 28 © Copyright 2010, Software Alchemy Maven Integration ● Creating a Grails app with Maven 2: mvn archetype:generate -DarchetypeGroupId=org.grails -DarchetypeArtifactId=grails-maven-archetype -DarchetypeVersion=1.3.4 -DgroupId=com.example -Dversion=0.1 -DartifactId=MyMavenApp cd MyMavenApp/ mvn initialize ● Supporting Eclipse: mvn -DdownloadSources=true -DdownloadJavadocs=true eclipse:eclipse
  29. 29. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 29 © Copyright 2010, Software Alchemy Ant Integration ● You can use Grails scripts in an Ant script ● You can use Ant tasks in your own Grails scripts, Example: ant.property(file:"${basedir}/application.properties") def appName = "${Ant.project.properties['app.name']}" def appVersion = "${Ant.project.properties['app.version']}" def appPath = "${appName}-${appVersion}" target(main: "Create an archive of the complete project source.") { ant.zip(destfile: "../${appPath}-dist.zip") { zipfileset(dir:"${basedir}", prefix:"${appPath}") { exclude(name:"target/**") exclude(name:"web-app/WEB-INF/classes/**") } } } setDefaultTarget(main)
  30. 30. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 30 © Copyright 2010, Software Alchemy External Deployment ● Build a WAR file using this command: grails dev war ● Deploy to your JavaEE compilant web container – WAR includes all Groovy and Grails JARs – WAR includes all infrastructure JARs – WAR includes DB driver JAR – WAR includes all plugins
  31. 31. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 31 © Copyright 2010, Software Alchemy Web Technologies ● Controllers ● Views: GSPs ● Tag libraries ● Filters
  32. 32. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 32 © Copyright 2010, Software Alchemy Controllers ● Controllers are Groovy classes that reside in the grails-app/controllers source directory ● Method names map to URL patterns, eg: http://localhost:8080/MyApp/employee/list – Maps to EmployeeController and list method ● View selection: – Use render to render a specific View component – Use redirect to tell the browser to redirect – Return a model Map to render this method's View, eg. list action renders list.gsp
  33. 33. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 33 © Copyright 2010, Software Alchemy Views: GSPs ● Very much like JSPs but uses Groovy as the scripting language; cavet: don't script! ● Use custom tags for view logic – Large built-in library – Easy to create your own ● GSP attributes: – standard JSP attribute scopes plus flash scope – named values in the action method's model Map ● Grails uses SiteMesh for layout control
  34. 34. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 34 © Copyright 2010, Software Alchemy Tag Libraries ● Tag libraries are Groovy classes that reside in the grails-app/taglib source directory ● Each method provides a custom tag, eg: class MyTags { def isAdmin = { attrs, body -> def user = attrs['user'] if ( user != null && checkUserPrivs(user) ) { out << body() } } } ● No configuration required ● Automatically available in all GSPs, eg: <g:isAdmin user=”${theUser}”>ADMIN CONTENT</g:isAdmin>
  35. 35. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 35 © Copyright 2010, Software Alchemy Request Filters ● Filters are Groovy classes that reside in the grails-app/conf source directory that end in Filters class SecurityFilters { def filters = { loginCheck(controller:'*', action:'*') { before = { if (params.controller == null) { redirect(action:'login') return true } else if(!session.user && !actionName.equals('login')) { redirect(action:'login') return false } } } } }
  36. 36. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 36 © Copyright 2010, Software Alchemy Transactions and Services ● Controller actions can be made transactional – Use Spring SessionFactory injection – Or use the withTransaction method ● Service components are a better solution – All classes that reside in the grails- app/services source directory – Use the def transactional = true for Spring transaction AOP wrapping – Inject the service into the controller: def storeService // auto-injects StoreService
  37. 37. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 37 © Copyright 2010, Software Alchemy Plugins ● Grails is a framework built on plugins ● Default plugins: – Hibernate: the Grails ORM (aka GORM) – Tomcat: the Grails default runtime environment ● Hundreds of additional plugins – Security (40) – Services (117) – JavaScript frameworks (74) – many more...
  38. 38. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 38 © Copyright 2010, Software Alchemy Spring Security Plugin ● Install the plugin: grails install-plugin spring-security-core ● Create the User and Role entities: grails s2-quickstart com.example.security User Role «javaPackage» com.example.security «entity» Role authority : String «entity» User username : String password : String enabled : boolean role 1 0..* «entity» UserRoleuser 1 /+authorities
  39. 39. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 39 © Copyright 2010, Software Alchemy BootStrap Roles and Users import com.example.security.*; class BootStrap { def springSecurityService def init = { servletContext -> // Define user role's def hrRepRole = Role.findByAuthority('ROLE_HR_REP') ?: new Role(authority: 'ROLE_HR_REP').save(failOnError: true) def hrMgrRole = Role.findByAuthority('ROLE_HR_MANAGER') ?: new Role(authority: 'ROLE_HR_MANAGER').save(failOnError: true) def adminRole = Role.findByAuthority('ROLE_ADMIN') ?: new Role(authority: 'ROLE_ADMIN').save(failOnError: true) // a few users: def adminUser = User.findByUsername('admin') ?: new User( username: 'admin', password: springSecurityService.encodePassword('admin'), enabled: true).save(failOnError: true) if (!adminUser.authorities.contains(adminRole)) { UserRole.create adminUser, adminRole } // and so on } }
  40. 40. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 40 © Copyright 2010, Software Alchemy Define Security Constraints ● Use annotations on controller actions, eg: import grails.plugins.springsecurity.Secured class DepartmentController { @Secured(['ROLE_HR_MANAGER', 'ROLE_HR_REP']) def list = { ... } @Secured(['ROLE_HR_MANAGER']) def create = { ... } @Secured(['ROLE_ADMIN']) def delete = { ... } } ● Or static URL rules in the Config.groovy file ● Or store the rules in the database
  41. 41. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 41 © Copyright 2010, Software Alchemy Grails Architecture Conv/Config Build tools Web techPlugins Groovy Getting Groovy w/ Grails Install Grails Create App Create Entity GUI Scaffolding Basic Domain Modeling Getting Started Domain Modeling Relationships Validation Enumerated types Derived properties Embedded properties Inheritance Domain Modeling
  42. 42. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 42 © Copyright 2010, Software Alchemy HrApp Use Cases View HR action history Employee Manager HR Rep HR Mgr View department staff Promote employee Issue pay raise for employee Confirm employee promotion Confirm employee pay raise Issue cost-of-living raise to department Hire employee Terminate employee Confirm employee hire Confirm employee termination Confirm department COL raise Create/update job roles
  43. 43. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 43 © Copyright 2010, Software Alchemy Domain Model is King!
  44. 44. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 44 © Copyright 2010, Software Alchemy Property Validations ● Property constraints are defined in the Domain model, eg: class Employee { // skipping property definitions static constraints = { firstName(nullable:false, blank:false, maxSize:32) lastName(nullable:false, blank:false, maxSize:64) dateOfBirth(nullable:true) homeAddress(nullable:false) homePhone(nullable:false) cellPhone(nullable:true) department(nullable:false) jobRole(nullable:true) salary(nullable:true, min:10000) proposedChange(nullable:true) // workflow properties user(nullable:false) status(nullable:false) }
  45. 45. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 45 © Copyright 2010, Software Alchemy Basic Enumerated Types ● Grails supports Java-style enums, eg: class Employee { // other properties Status status enum Status { CREATED, HIRED, DISCIPLINARY_REVIEW, TERMINATED; static def getActiveStatuses = { return [HIRED, DISCIPLINARY_REVIEW] } } // more code } ● ...but the enum name is stored in the DB field which is a bit wasteful, so... «enumeratedType» Status +CREATED +HIRED +DISCIPLARY_REVIEW +TERMINATED «entity» Employee firstName : String lastName : String ... status : Status
  46. 46. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 46 © Copyright 2010, Software Alchemy Enumerated Types with Ids ● You can define an id field in the enum, eg: class EmployeeAction { // other properties enum ActionType { HIRE('HI'), RAISE('RA'), COL_RAISE('CR'), PROMOTE('PO'), TERMINATE('TE'); final String id ActionType(String id) { this.id = id } } // more code } ● ...so now the DB field is a two-char value. «enumeratedType» Status +HIRE('HI') +RAISE('RA') +COL_RAISE('CR') +PROMOTE('PO') +TERMINATE('TE') id : String «entity» EmployeeAction type : ActionType employee : Employee newRole : JobRole ...
  47. 47. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 47 © Copyright 2010, Software Alchemy Derived Properties ● Also know as transient properties, eg: class Employee { // Properties Date dateOfBirth // Derived properties Integer getAge() { // corner case if ( dateOfBirth == null ) return null; // calculate and memoize the employee's age _age = _age ?: DateUtils.dateDiffYears(new Date(), dateOfBirth) return _age } private Integer _age // GORM constraints static transients = [ 'age', ... ] } «entity» Employee dateOfBirth : Date /age : Integer ...
  48. 48. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 48 © Copyright 2010, Software Alchemy Derived Relationships ● You can do the same with computed relationships, eg: class Employee { // Derived properties List<EmployeeAction> getHistory() { // calculate and memoize the employee's HR history _history = _history ?: EmployeeAction.findAllByEmployee( this, [sort:'proposedDate', order:'asc'] ) return _history } private List<EmployeeAction> _history // GORM constraints static transients = [ 'age', 'history', ... ] } «entity» EmployeeAction/history *«entity» Employee
  49. 49. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 49 © Copyright 2010, Software Alchemy Embedded Properties ● Grails encourages rich object models even for non-Entity objects, eg: class Employee { // Properties Address homeAddress PhoneNumber homePhone PhoneNumber cellPhone // GORM constraints static embedded = [ 'homeAddress', 'homePhone', 'cellPhone' ] } class PhoneNumber { // Properties String areaCode String prefix String number // GORM constraints... } «entity» Employee homeAddress : Address homePhone : PhoneNumber cellPhone : PhoneNumber «valueObject» PhoneNumber areaCode : String prefix : String number : String
  50. 50. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 50 © Copyright 2010, Software Alchemy Embedded Properties (2) ● GORM creates a DB schema with each field of the Value Object embedded in the fields of the Entity. class Employee { // Properties Address homeAddress PhoneNumber homePhone PhoneNumber cellPhone }
  51. 51. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 51 © Copyright 2010, Software Alchemy Relationships ● Grails supports: one-to-one, one-to-many and many-to-many ● Grails supports uni- and bi-directional relationships ● Grails support ownership, with cascading deletes ● Grails supports unordered sets, sorted sets, and lists (with ordering index)
  52. 52. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 52 © Copyright 2010, Software Alchemy One-to-One Relationships class Employee { // Properties Department department JobRole jobRole User user // GORM constraints static constraints = { department(nullable:false) jobRole(nullable:true) user(nullable:false) } «entity» JobRolejobRole 0..1 «entity» User {from com.example.security} user1 «entity» Employee user : User jobRole : JobRole department : Department «entity» Department department 1
  53. 53. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 53 © Copyright 2010, Software Alchemy One-to-Many class HRRepresentative extends Employee { // Properties Set<Department> departments // GORM constraints static hasMany = [ 'departments' : Department ] } «entity» HRRepresentative departments : Set<Department> «entity» Department departments *
  54. 54. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 54 © Copyright 2010, Software Alchemy Inheritance ● Inheritance is supported with little to no configuration ● By default, the whole hierarchy is stored in one table ● You can configure Grails to use multiple tables ● ...but be aware of the DB performance impact of multiple selects and table joins
  55. 55. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 55 © Copyright 2010, Software Alchemy Inheritance (2) class Employee { ... } class HRRepresentative extends Employee { ... } class Manager extends Employee { ... } class Engineer extends Employee { ... } «entity» Employee «entity» HRRepresentative «entity» Manager «entity» Engineer
  56. 56. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 56 © Copyright 2010, Software Alchemy Inheritance (3) ● The resulting DB table:
  57. 57. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 57 © Copyright 2010, Software Alchemy Grails Architecture Conv/Config Build tools Web techPlugins Groovy Getting Groovy w/ Grails Install Grails Create App Create Entity GUI Scaffolding Basic Domain Modeling Getting Started Domain Modeling Relationships Validation Enumerated types Derived properties Embedded properties Inheritance Q & A
  58. 58. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 58 © Copyright 2010, Software Alchemy Ten Great Topics Not Covered 1) Supports unit and integration testing 2) Supports RESTful URL patterns 3) Supports Java and Spring integration 4) Supports multiple environments 5) Integration to legacy DBs using Hibernate mappings 6) Supports turning Service components into Web Services 7) Easy to create your own plugins for cross-team sharing 8) Supports other continuous integration tools: Hudson, Ivy, etc 9) Supports data auditing and time stamping w/ GORM event model 10) Supports Ajax and Spring Web Flows
  59. 59. Rochester JUG: 9-Nov-2010 Bryan Basham – Getting Groovy with Grails Slide 59 © Copyright 2010, Software Alchemy Resources ● Groovy (http://groovy.codehaus.org/) – Reference docs (click here) – Reference card (click here) ● Grails (http://www.grails.org/) – Reference docs (click here) ● Eclipse plugin (http://dist.springsource.org/release/GRECLIPSE/e3.6/) ● The Definitive Guide to Grails (by Rocher and Brown, Apress)
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×