
- •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

42 |
CHAPTER 2 Groovy by example |
assert stadium.longitude > -123 && stadium.longitude < -71
}
}
@Test
void testGetGame() {
GameResult gr = ggd.getGame 'bos','col','1' assert 'Boston Red Sox' == gr.away
assert 'Colorado Rockies' == gr.home assert 4 == gr.aScore.toInteger() assert 3 == gr.hScore.toInteger()
}
}
Check the World Series game
This is a standard JUnit 4 test case. I have much more to say about Groovy testing capabilities in chapter 6 on testing, but here’s a simple example. There’s nothing inherently Groovy about this class except that (1) I used the map-based constructor to instantiate the fixture, (2) optional parentheses were left out wherever possible, and
(3) no explicit public or private keywords were needed. Otherwise, this is just a regular test case, and it works as usual.
What have I discussed in this section?
■Groovy has a convenient syntax for maps.
■XML parsing and extracting data are easy, as in the previous section.
■Groovy has a slashy syntax for regular expressions.
■Groovy classes work with JUnit tests.
There’s one final piece of the puzzle needed, which is the driver used to call the system for each date. I use a “groovlet” for this purpose in the next section.
2.3.3HTML builders and groovlets
The classes used so far access XML box score information and convert it into a series of game result objects. For the view layer, however, I need objects in a form that can be processed by JavaScript. There are several ways to accomplish this, but one of them is to use an XML builder to write out the information in XML form.11
GENERATING XML
The standard Groovy library includes a class called groovy.xml.MarkupBuilder,12 which is one of several builders (much like the SwingBuilder shown at the beginning of this chapter) in the standard library. Each of the builders intercepts method calls that don’t exist (so-called pretended methods) and constructs nodes out of them to make a tree structure. The tree is then exported appropriately for that kind of builder.
This is actually easier to see than to explain. Consider the GameResult class from the previous section, which held the home and away team names and scores and a reference to a Stadium object. Here’s the syntax for creating XML out of that object:
11The data could just as easily be written in JSON format. Other JSON examples are used throughout the book.
12I would bet that if this class were created today, it would be called XmlBuilder instead.
www.it-ebooks.info
Groovy Baseball |
43 |
MarkupBuilder builder = new MarkupBuilder() builder.games {
results.each { g -> game(
outcome:"$g.away $g.aScore, $g.home $g.hScore", lat:g.stadium.latitude,
lng:g.stadium.longitude
)
}
}
After instantiating the MarkupBuilder and calling the reference builder, the second line invokes the games method on it. It may not look like a method, but recall that in Groovy, if a closure is the last argument to a method it can be placed outside the parentheses, and here I’m using optional parentheses. Of course, there’s no method called games in MarkupBuilder. That makes it a pretended method, and the builder intercepts that method call and creates a node out of it. In a MarkupBuilder that means it will ultimately create an XML element called games. The closure syntax implies that the next elements will be child elements of games.
Inside the closure the code iterates over each contained result, assigning it to the dummy variable g. For each GameResult g, the builder creates an element called game. The parentheses on game imply that game will contain attributes. In this case, each game has an outcome, a lat, and a lng.
Here’s the output of the MarkupBuilder:
<games>
<game outcome='Boston Red Sox 4, Colorado Rockies 3' lat='39.7564956' lng='-104.9940163' />
</games>
If there had been a dozen games that day there would a <game> element for each one of them. The bottom line is that in Groovy, generating XML is about as easy as parsing it.
SERVER-SIDE PROCESSING WITH GROOVLETS
To drive the whole system I need a server-side component that receives the needed date and calls the GetGameData class to retrieve the games, which are then returned in XML form. Groovy has a component known as a groovlet to make that all easy.
A groovlet is a script that is executed by a class called groovy.servlet.GroovyServlet. This class is part of the Groovy standard library. Like any servlet, it needs to be declared in the web.xml deployment descriptor for a web application and mapped to a particular URL pattern. In this case I chose the pattern *.groovy. Here’s the excerpt from the deployment descriptor:
<servlet> <servlet-name>GroovyServlet</servlet-name>
<servlet-class>groovy.servlet.GroovyServlet</servlet-class> </servlet>
www.it-ebooks.info

44 |
CHAPTER 2 Groovy by example |
<servlet-mapping> <servlet-name>GroovyServlet</servlet-name> <url-pattern>*.groovy</url-pattern>
</servlet-mapping>
The Groovy Baseball application will therefore send all URLs ending in .groovy through the GroovyServlet, which will execute them. Groovlets executed this way are deployed as source code rather than as compiled classes under WEB-INF.13 Groovlets also contain a set of implicit objects representing the request, response, input parameters, and more.
The following listing contains the complete content of the groovlet that drives the Groovy Baseball system.
Listing 2.10 GameServlet.groovy: a groovlet for Groovy Baseball
import beans.GameResult; import beans.Stadium; import service.GetGameData;
response.contentType = 'text/xml' def month = params.month
def day = params.day def year = params.year
Set the content type of the response
Extract input parameters
m = month.toInteger() < 10 ? '0' + month : month d = day.toInteger() < 10 ? '0' + day : day
y = year.toInteger() + ''
ggd = new GetGameData(month:m,day:d,year:y) results = ggd.games
Retrieve games for that date
html.games { |
|
Use a builder to |
|
||
results.each { g -> |
generate XML |
|
game( |
|
outcome:"$g.away $g.aScore, $g.home $g.hScore", lat:g.stadium.latitude,
lng:g.stadium.longitude
)
}
}
The groovlet can set response headers, here setting the output to XML. Input parameters populate a map of strings called params, which can be accessed in the usual way. The URL requires two-digit days and two-digit months, so a zero is prepended when necessary. After retrieving the games for that date the output is generated using the implicit MarkupBuilder. There’s no need to instantiate a MarkupBuilder in this case, because groovlets already contain one, called html.
The groovlet is called from a regular web page, using a URL of the form http://.../ groovybaseball/GroovyService.groovy?month=10&day=28&year=2007. The XML data is written to the output stream, which can then be processed by JavaScript.
13 The details are discussed in chapter 10 on web applications.
www.it-ebooks.info