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

Building and testing web applications
This chapter covers
■Groovy servlets and ServletCategory
■Groovlets
■Unit and integration testing of web apps
■The Groovy killer app, Grails
While Java on the desktop has its adherents, Java found a true home on the server side. Java’s growth and adoption in the early days neatly follow that of the web itself. It’s a rare Java developer who hasn’t at least worked on a web application.
In this chapter I’m going to look at modern web application development and where Groovy can make the process simpler and easier. Sometimes Groovy just simplifies the code. Other times it provides helpful testing tools, like Gradle and HTTPBuilder. Finally, there’s the most famous framework in the Groovy ecosystem, Grails. I’ll review them all and try to place them in the overall context of web applications.
Figure 10.1 is a guide to the technologies discussed in this chapter.
257
www.it-ebooks.info

258 |
CHAPTER 10 Building and testing web applications |
|||
|
Spring web |
Gradle |
|
|
Java |
integration |
Java + |
||
mocks |
||||
testing |
testing |
Groovy |
||
|
||||
|
|
|
testing |
|
Groovy |
Servlet |
Groovlets |
|
|
language |
category |
|
||
|
|
Groovy |
HttpBuilder |
Grails |
projects |
|
|
Figure 10.1 Guide to the technologies in this chapter. Spring provides mock objects for testing that are also used in Grails. Using plugins and some configuration, Gradle builds can do integration testing of web applications. The ServletCategory class makes session, request, and other objects easier to use. Groovlets are a quick way to build simple applications. Finally, the HTTPBuilder project provides a programmatic web client, and Grails applications use Groovy DSLs and elegant metaprogramming to combine Spring and Hibernate in a standard convention-over-configuration framework.
10.1 Groovy servlets and ServletCategory
Groovy doesn’t add a lot to basic servlet development, but the standard library does provide a category class that illustrates what Groovy’s metaprogramming can do. The following listing shows a trivial servlet, HelloGroovyServlet.groovy, part of a web application implemented in Groovy.
Listing 10.1 A simple servlet implemented in Groovy
class HelloGroovyServlet extends HttpServlet {
void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.writer.print 'Hello from a Groovy Servlet!'
}
}
Other than the normal Groovy simplifications (omitting the word public, lack of semicolons, use of writer rather than getWriter(), and the optional parentheses on print), this isn’t much different from a Java implementation. Use Groovy if you prefer the slightly shorter code, but really the choice of language is a matter of style.
What Groovy does provide is a category class to simplify the code even further. Category classes are an example of Groovy’s metaprogramming capabilities. They show how to add methods to existing classes in a specified block of code, unlike using the metaclass object to add them everywhere in your program. If you ever wanted to understand categories, ServletCategory is a great, extremely simple, useful example.
www.it-ebooks.info

Groovy servlets and ServletCategory |
259 |
Figure 10.2 The GroovyDocs for ServletCategory. Each method is static and is added to the class listed in the first argument.
CATEGORIES Use a Groovy category to add methods to existing classes when you only need those methods under specific circumstances. Category methods are only available in a use block.
Figure 10.2 shows a sample of the GroovyDocs for the groovy.servlet.ServletCategory class.
A Groovy category consists of static methods having one or more arguments. The first argument to the method is the class that receives the method. In ServletCategory there are only four methods, with lots of overloads (see table 10.1).
Table 10.1 The ServletCategory methods for different scopes
Method Name |
First Argument |
|
|
get(arg, String key) |
ServletContext, HttpSession, |
|
ServletRequest, PageContext |
getAt(arg, String key) |
Same as above |
putAt(arg, String key, Object value) |
Same as above |
set(arg, String key, Object value) |
Same as above |
|
|
www.it-ebooks.info

260 |
CHAPTER 10 Building and testing web applications |
See a pattern? The job of this category is to make it easy to add attributes at page scope (PageContext), request scope (ServletRequest), session scope (HttpSession), and application scope (ServletContext). Remember that in Groovy all operators correspond to methods. In this case, the get and set methods correspond to the dot operator, and the getAt and putAt methods implement the array subscript operator. Before I show an example, take a look at a portion of the actual implementation class, groovy.servlet.ServletCategory, in the following listing, implemented in Java.
Listing 10.2 Methods for HttpSession from groovy.servlet.ServletCategory
public class ServletCategory {
public static Object get(HttpSession session, String key) { return session.getAttribute(key);
}
...
public static Object getAt(HttpSession session, String key) { return session.getAttribute(key);
}
...
public static void set(HttpSession session, String key, Object value) { session.setAttribute(key, value);
}
...
public static void putAt(HttpSession session, String key, Object value) { session.setAttribute(key, value);
}
}
The first interesting thing to note is that this class is written in Java (!), even though it’s being used in Groovy. When overloading operators, Groovy doesn’t care which language you use to implement the methods, only that you use the operators that delegate to the methods in Groovy. In this case, I don’t even plan to use the methods directly. Instead, I’m using the dot operator and/or the array subscript notation to invoke them implicitly.
The other important detail here is that all the methods are delegating to either the getAttribute or setAttribute method. The effect is that either the dot operator or the subscript operator can be used to add attributes to the page, request, session, or application scope.
SERVLETCATEGORY Whether you use ServletCategory or not, its combination of metaprogramming and operator overloading make it an excellent example of how Groovy helps Java.
www.it-ebooks.info

Groovy servlets and ServletCategory |
261 |
Categories in Groovy 2.0
Groovy 2.0 introduced an alternative syntax for defining categories. In the ServletCategory discussed in this section, the category class contains static methods whose first argument is the class being modified. In the new notation you can use annotations and instance methods instead.
As an example, consider formatting numbers as currency. The java.text.NumberFormat class has a method called getCurrencyInstance, which has both a no-arg method that formats for the current locale and an overloaded version that takes a java.util.Locale argument. The classic way to add an asCurrency method to Number that employs the currency formatter is
import java.text.NumberFormat
class CurrencyCategory {
static String asCurrency(Number amount) { NumberFormat.currencyInstance.format(amount)
}
static String asCurrency(Number amount, Locale loc) { NumberFormat.getCurrencyInstance(loc).format(amount)
}
}
use(CurrencyCategory) {
def amount = 1234567.89012 println amount.asCurrency()
println amount.asCurrency(Locale.GERMANY)
println amount.asCurrency(new Locale('hin','IN'))
}
The new way to implement a category uses the @Category annotation, which takes the class to be modified as an argument. Then instance methods are used inside the category, and the this reference refers to the object where the category is invoked. The analogous implementation for the currency category is
import java.text.NumberFormat
@Category(Number)
class AnnotationCurrencyCategory { String asCurrency() {
NumberFormat.currencyInstance.format(this)
}
String asCurrency(Locale loc) { NumberFormat.getCurrencyInstance(loc).format(this)
}
}
Number.mixin AnnotationCurrencyCategory def amount = 1234567.89012
println amount.asCurrency()
println amount.asCurrency(Locale.GERMANY) println amount.asCurrency(new Locale('hin','IN'))
www.it-ebooks.info

262 |
CHAPTER 10 Building and testing web applications |
(continued)
Note also the use of the mixin method to add the category to the Number class.
Presumably, if the ServletCategory was being implemented now, it would use the annotation approach. The result is the same either way, of course.1
An example will make this clear. The next listing shows a class called HelloNameServlet, implemented in Groovy, which receives a name parameter and replies with the standard welcome.1
Listing 10.3 The HelloNameServlet class, which uses the ServletCategory
import groovy.servlet.ServletCategory;
import javax.servlet.ServletException import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse
class HelloNameServlet extends HttpServlet {
|
void doGet(HttpServletRequest request, HttpServletResponse response) |
||||||
|
|
throws ServletException, IOException { |
Make category |
||||
Get session |
|
def session = request.session |
|
||||
|
|
methods available |
|||||
from request |
|
use (ServletCategory) { |
|
|
|||
|
|
|
|
|
|
||
|
|
request.name = 'Hello, ' + |
|
|
Delegate to get/set and |
||
|
|
(request.getParameter('name') ?: 'World') |
|
||||
|
|
|
|||||
|
|
session['count'] = (session.count ?: 0) + 1 |
|
|
getAt/putAt methods |
}
request.getRequestDispatcher('hello.jsp')
.forward(request,response)
}
}
This class works with attributes in both the request and the session. After getting the session from the request (which is standard “property access means get method” style, not the category), the use block defines the region where the category is active. Inside the use block, a name attribute is added to the request using the dot notation, whose value is either supplied by the user in the form of a parameter, or consists of the default value World. Next, a count attribute is placed in the session; its value is either incremented from its existing value or set to 1 if it doesn’t already exist.
The test class, HelloNameServletTest, is shown in the next listing. It uses the Spring API mock objects to test the doGet method both with and without a supplied name.
Listing 10.4 The HelloNameServletTest class, which uses Spring’s mock objects
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
1 The book source code includes the two ways of doing the currency category as well as a test case.
www.it-ebooks.info