- •brief contents
- •contents
- •foreword
- •preface
- •acknowledgments
- •about this book
- •Roadmap
- •Code conventions and downloads
- •Author Online
- •About the author
- •about the cover illustration
- •1 Why add Groovy to Java?
- •1.1 Issues with Java
- •1.1.1 Is static typing a bug or a feature?
- •1.1.2 Methods must be in a class, even if you don’t need or want one
- •1.1.3 Java is overly verbose
- •1.1.4 Groovy makes testing Java much easier
- •1.1.5 Groovy tools simplify your build
- •1.2 Groovy features that help Java
- •1.3 Java use cases and how Groovy helps
- •1.3.1 Spring framework support for Groovy
- •1.3.2 Simplified database access
- •1.3.3 Building and accessing web services
- •1.3.4 Web application enhancements
- •1.4 Summary
- •2 Groovy by example
- •2.1 Hello, Groovy
- •2.2 Accessing Google Chart Tools
- •2.2.1 Assembling the URL with query string
- •2.2.2 Transmitting the URL
- •2.2.3 Creating a UI with SwingBuilder
- •2.3 Groovy Baseball
- •2.3.1 Database data and Plain Old Groovy Objects
- •2.3.2 Parsing XML
- •2.3.3 HTML builders and groovlets
- •2.4 Summary
- •3 Code-level integration
- •3.1 Integrating Java with other languages
- •3.2 Executing Groovy scripts from Java
- •3.2.1 Using JSR223 scripting for the Java Platform API
- •3.2.2 Working with the Groovy Eval class
- •3.2.3 Working with the GroovyShell class
- •3.2.4 Calling Groovy from Java the easy way
- •3.2.5 Calling Java from Groovy
- •3.3 Summary
- •4 Using Groovy features in Java
- •4.1 Treating POJOs like POGOs
- •4.2 Implementing operator overloading in Java
- •4.3 Making Java library classes better: the Groovy JDK
- •4.4 Cool AST transformations
- •4.4.1 Delegating to contained objects
- •4.4.2 Creating immutable objects
- •4.4.3 Creating singletons
- •4.5 Working with XML
- •4.6 Working with JSON data
- •4.7 Summary
- •5 Build processes
- •5.1 The build challenge
- •5.2 The Java approach, part 1: Ant
- •5.3 Making Ant Groovy
- •5.3.1 The <groovy> Ant task
- •5.3.2 The <groovyc> Ant task
- •5.3.3 Writing your build in Groovy with AntBuilder
- •5.3.4 Custom build scripts with Gant
- •5.3.5 Ant summary
- •5.4 The Java approach, part 2: Maven
- •5.4.2 The GMaven project
- •5.4.3 Maven summary
- •5.5 Grapes and @Grab
- •5.6 The Gradle build system
- •5.6.1 Basic Gradle builds
- •5.6.2 Interesting configurations
- •5.7 Summary
- •6 Testing Groovy and Java projects
- •6.1 Working with JUnit
- •6.1.1 A Java test for the Groovy implementation
- •6.1.2 A Groovy test for the Java implementation
- •6.1.3 A GroovyTestCase test for a Java implementation
- •6.2 Testing scripts written in Groovy
- •6.2.1 Useful subclasses of GroovyTestCase: GroovyShellTestCase
- •6.2.2 Useful subclasses of GroovyTestCase: GroovyLogTestCase
- •6.3 Testing classes in isolation
- •6.3.1 Coerced closures
- •6.3.2 The Expando class
- •6.3.3 StubFor and MockFor
- •6.4 The future of testing: Spock
- •6.4.1 The Search for Spock
- •6.4.2 Test well, and prosper
- •6.4.4 The trouble with tribbles
- •6.4.5 Other Spock capabilities
- •6.5 Summary
- •7 The Spring framework
- •7.1 A Spring application
- •7.2 Refreshable beans
- •7.3 Spring AOP with Groovy beans
- •7.4 Inline scripted beans
- •7.5 Groovy with JavaConfig
- •7.6 Building beans with the Grails BeanBuilder
- •7.7 Summary
- •8 Database access
- •8.1 The Java approach, part 1: JDBC
- •8.2 The Groovy approach, part 1: groovy.sql.Sql
- •8.3 The Java approach, part 2: Hibernate and JPA
- •8.4 The Groovy approach, part 2: Groovy and GORM
- •8.4.1 Groovy simplifications
- •8.5 Groovy and NoSQL databases
- •8.5.1 Populating Groovy vampires
- •8.5.2 Querying and mapping MongoDB data
- •8.6 Summary
- •9 RESTful web services
- •9.1 The REST architecture
- •9.3 Implementing JAX-RS with Groovy
- •9.4 RESTful Clients
- •9.5 Hypermedia
- •9.5.1 A simple example: Rotten Tomatoes
- •9.5.2 Adding transitional links
- •9.5.3 Adding structural links
- •9.5.4 Using a JsonBuilder to control the output
- •9.6 Other Groovy approaches
- •9.6.1 Groovlets
- •9.6.2 Ratpack
- •9.6.3 Grails and REST
- •9.7 Summary
- •10 Building and testing web applications
- •10.1 Groovy servlets and ServletCategory
- •10.2 Easy server-side development with groovlets
- •10.2.1 A “Hello, World!” groovlet
- •10.2.2 Implicit variables in groovlets
- •10.3.2 Integration testing with Gradle
- •10.3.3 Automating Jetty in the Gradle build
- •10.4 Grails: the Groovy “killer app”
- •10.4.1 The quest for the holy Grails
- •10.5 Summary
- •A.1 Installing a JDK
- •A.2 Installing Groovy
- •A.3 Testing your installation
- •A.4 IDE support
- •A.5 Installing other projects in the Groovy ecosystem
- •B.1 Scripts and the traditional example
- •B.2 Variables, numbers, and strings
- •B.2.1 Numbers
- •B.2.2 Strings and Groovy strings
- •B.3 Plain Old Groovy Objects
- •B.4 Collections
- •B.4.1 Ranges
- •B.4.2 Lists
- •B.4.3 Maps
- •B.5 Closures
- •B.6 Loops and conditionals
- •B.6.1 Loops
- •B.6.2 Conditionals
- •B.6.3 Elvis
- •B.6.4 Safe de-reference
- •B.7 File I/O
- •B.8.1 Parsing and slurping XML
- •B.8.2 Generating XML
- •B.8.3 Validation
- •B.9 JSON support
- •B.9.1 Slurping JSON
- •B.9.2 Building JSON
- •index
- •Symbols
Other Groovy approaches |
253 |
(continued)
3Structural links in the body are added through a special JAXB annotation.
4You can manage the parsing and response generation stages yourself by writing a provider class that implements MessageBodyReader and/or MessageBodyWriter.
Between the transitional links, the structural links with the JAXB serializer, and the Groovy JsonBuilder, hopefully you now have enough mechanisms to implement hypermedia links in any way your application requires. The choice of which to use is largely a matter of style, but there are some guidelines:
■Structural links are contained in the response, so the client has to parse the response to get them.
■Transitional links are in the HTTP headers. That gets them out of the response but forces the client to parse the HTTP response headers to retrieve them.
■Custom links can be anything, so they must be clearly documented.
Examples of all three approaches can be found on the web.
9.6Other Groovy approaches
There are three other approaches in the Groovy ecosystem that I should mention for RESTful web services. Here I’ll specifically discuss groovlets, the Ratpack project, and Grails.
9.6.1Groovlets
Groovlets are discussed in chapter 10 on web applications as well as the simple example in chapter 2, but essentially they’re groovy scripts that receive HTTP requests and return HTTP responses. Groovlets contain many implicit variables, including request, response, session, and params (to hold input variables).
In a groovlet you can use the getMethod method on the request object to determine if the request is a GET, PUT, POST, or DELETE. Then you can build the response accordingly.
The book source code has a project in chapter 10 called SongService, which demonstrates how to use a groovlet. The service itself is a groovlet, which is shown in the following listing.
Listing 9.11 A groovlet that processes and produces XML
def dao = SongDAO.instance
switch (request.method) { case 'GET' :
if (params?.id) { |
Implicit |
||
MarkupBuilder |
|||
def s = dao.getSong(params.id) |
|||
html |
|||
html.song(id:s.id) { |
|
||
|
|
www.it-ebooks.info
254 |
CHAPTER 9 RESTful web services |
|
title s.title |
|
artist s.artist |
|
year s.year |
|
} |
|
} else { |
|
def songs = dao.getAllSongs() |
|
html.songs { |
songs.each { s -> song(id:s.id) {
title s.title artist s.artist year s.year
}
}
}
}
break case 'POST' :
def data = new XmlSlurper().parse(request.reader) def s = new Song(id:data.@id,title:data.title,
artist:data.artist,year:data.year) def exists = dao.exists(s.id)
Converting request data to XML
if (!exists) { dao.addSong s
response.addHeader 'Location', "http://localhost:8080/GroovySongs/SongService.groovy?id=${s.id}" out.print "${s.title} added with id ${s.id}"
} else {
out.print "${s.title} already exists"
}
break
case 'DELETE' : dao.deleteSong params.id
out.print "${params.id} deleted" break
default:
print 'Only GET, POST, and DELETE supported'
}
The groovlet uses request.method in a switch statement to determine the correct implementation. Then it uses a built-in MarkupBuilder called html to produce XML, and an XmlSlurper to convert XML to song instances. Now that groovlets have a builtin JsonBuilder as well,22 JSON could easily be used instead.
This approach is pretty low-level, but it may be useful for quick-and-dirty implementations or if you need such detailed control.
22That’s my great contribution to Groovy—the implicit json object in groovlets, which I not only added, but with which I managed to break the build in the process. Sigh. If you’re interested, details can be found at http://mng.bz/5Vn6.
www.it-ebooks.info
Other Groovy approaches |
255 |
9.6.2Ratpack
The second alternative is to look at the Ratpack project (https://github.com/ratpack/ ratpack). Ratpack is a Groovy project that follows the same ideas as the Sinatra23 project in the Ruby world. Ratpack is called a “micro” framework, in that you write simple Groovy scripts that govern how to handle individual requests.
For example, a simple Ratpack script looks like this:
get("/person/:personid") {
"This is the page for person ${urlparams.personid}"
}
post("/submit") {
// handle form submission here
}
put("/some-resource") { // create the resource
}
delete("/some-resource") { // delete the resource
}
The project shows a lot of promise, and Sinatra is very popular in the Ruby world, so it’s probably worth a look. The project has recently come under the control of Luke Daley, who is a major player in the Groovy world, so I expect significant improvements soon.
9.6.3Grails and REST
Finally, Grails has REST capabilities as well. For example, in a Grails application you can edit the URLMappings.groovy file as follows:
static mappings = { "/product/$id?"(resource:"product")
}
The result is that GET, POST, PUT, and DELETE requests for products will be directed to the show, save, update, and delete actions in the ProductController, respectively. Grails also automatically parses and generates XML and/or JSON, as desired.
There’s also a JAX-RS plugin available for Grails. At the moment it’s based on JAX-RS version 1, but the implementation can use either the Jersey reference implementation or Restlets. Of course, once again, nothing is said about hypermedia in either case, though anything you can do in Groovy you can, of course, do in Grails as well.
REST capabilities are a major design goal of Grails 3.0, so by then the situation will no doubt change.
23 Sinatra, Ratpack, get it? If nothing else, it’s a great name.
www.it-ebooks.info