
- •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
Easy server-side development with groovlets |
263 |
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpSession;
class HelloNameServletTest {
HelloNameServlet servlet = new HelloNameServlet()
@Test
void testDoGetWithNoName() {
MockHttpServletRequest request = new MockHttpServletRequest() MockHttpServletResponse response = new MockHttpServletResponse() MockHttpSession session = new MockHttpSession()
request.session = session servlet.doGet(request, response)
assert 'hello.jsp' == response.forwardedUrl
assert request.getAttribute("name") == 'Hello, World' assert session.getAttribute("count") == 1
}
@Test
void testDoGetWithName() {
MockHttpServletRequest request = new MockHttpServletRequest() MockHttpServletResponse response = new MockHttpServletResponse() MockHttpSession session = new MockHttpSession()
request.session = session request.setParameter('name','Dolly') servlet.doGet(request, response)
assert 'hello.jsp' == response.forwardedUrl
assert request.getAttribute("name") == 'Hello, Dolly' assert session.getAttribute("count") == 1
}
}
The ServletCategory isn’t needed in the tests, because I’m already using mock objects rather than the Servlet API classes. Note that the tests check both the request and session attributes and the forwarded URL from the doGet method. The ServletCategory class is a simple example of how to use Groovy’s metaprogramming capabilities to simplify an API.
As a simple alternative to normal servlet development, Groovy provides groovlets.
10.2 Easy server-side development with groovlets
Groovlets are groovy scripts that are executed in response to HTTP requests. A built-in library class called groovy.servlet.GroovyServlet executes them. Like all Groovy scripts, they’re associated with a binding that holds many pre-instantiated variables.
To use a groovlet, first configure the GroovyServlet to receive mapped requests. A typical way of doing so is to add the following XML to the standard web application deployment descriptor, web.xml:
<servlet> <servlet-name>Groovy</servlet-name>
<servlet-class>groovy.servlet.GroovyServlet</servlet-class> </servlet>
<servlet-mapping> <servlet-name>Groovy</servlet-name>
www.it-ebooks.info

264 |
CHAPTER 10 Building and testing web applications |
<url-pattern>*.groovy</url-pattern> </servlet-mapping>
The GroovyServlet class is part of the standard Groovy library. Here it’s mapped to the URL pattern *.groovy, which means that any URL that ends in that pattern will be directed to this servlet. For example, the URL http://localhost/.../hello.groovy would match a script named hello.groovy in the root of the web application. Keep in mind that this is literally the source file, not the compiled class.
GROOVLETS Groovlets are deployed as source code, not compiled.
When invoked, the GroovyServlet class finds the script whose name ends the URL, pre-instantiates a series of variables, creates an instance of the GroovyScriptEngine class, and executes the script. The actual script code can be placed in any accessible directory from the web application root, or in any subdirectory of /WEB-INF/groovy.
The key to the simplicity of groovlets is this already-configured infrastructure. With this in place a developer has a lot less work to do.
10.2.1A “Hello, World!” groovlet
Because every technology needs a “Hello, World!” application, here’s a groovlet to greet the user. Assume that the GroovyServlet has already been configured, and add a file called hello.groovy in the root of a web application. In a standard Maven structure that would be src/main/webapp/hello.groovy. The contents of the groovlet are
name = params.name ?: 'World' println "Hello, $name!"
It’s a simple groovlet, but it should still be tested. Integration-testing of web applications is discussed later in this chapter, but the syntax in the next listing uses the same mechanism for transmitting a GET request (use the Groovy JDK to convert a string to a URL and then call URL’s getText method) that was used in several earlier chapters.
Listing 10.5 HelloGroovletTest, an integration test for the hello groovlet
class HelloGroovletTest { int port = 8163
@Test
void testHelloGroovletWithNoName() { String response =
"http://localhost:$port/HelloGroovlet/hello.groovy"
.toURL().text
assert 'Hello, World!' == response.trim()
}
@Test
void testHelloGroovletWithName() { String response =
"http://localhost:$port/HelloGroovlet/hello.groovy?name=Dolly"
.toURL().text
www.it-ebooks.info

Easy server-side development with groovlets |
265 |
assert 'Hello, Dolly!' == response.trim()
}
}
There’s nothing particularly surprising or unusual about this test, which is simple because the groovlet only responds to GET requests.
Unit tests are also doable, based on the fact that the GroovyServlet is executing the groovlet as a script with predefined variables. For example, the next listing shows a unit test for the groovlet that uses an instance of the GroovyShell class and the Binding class in a manner similar to that described in chapter 6 on testing.
Listing 10.6 A unit test for the groovlet using GroovyShell and Binding
class HelloGroovletUnitTest {
String groovlet = 'src/main/webapp/hello.groovy' GroovyShell shell
Binding binding = new Binding() StringWriter content = new StringWriter()
@Before |
Setting the |
||
void setUp() { |
params map |
||
binding.params = [:] |
|
|
|
|
|
|
|
binding.out = new PrintWriter(content) |
|
|
|
shell = new GroovyShell(binding) |
|
|
|
} |
|
|
|
@Test
void testGroovletWithNoName() { shell.evaluate(new File("$groovlet"))
assert 'Hello, World!' == content.toString().trim()
}
@Test
void testGroovletWithName() { binding.params = [name:'Dolly'] shell.evaluate(new File("$groovlet"))
assert 'Hello, Dolly!' == content.toString().trim()
}
}
Capturing the output stream
The interesting parts of this test are first that the groovlet expects a map of input parameters, so the test has to provide one, and that I need a way to capture the output stream from the groovlet, which is done through the out variable of the binding.
Recall from chapter 6 that Groovy also provides a subclass of GroovyTestCase, called GroovyShellTestCase, which is designed to test scripts like this. The following listing shows the same unit test using GroovyShellTestCase. Note that it’s noticeably simpler.
Listing 10.7 Using GroovyShellTestCase to simplify unit-testing groovlets
class HelloGroovletShellTest extends GroovyShellTestCase { String groovlet = 'src/main/webapp/hello.groovy' StringWriter content = new StringWriter()
def capturedOut = new PrintWriter(content)
www.it-ebooks.info

266 |
CHAPTER 10 Building and testing web applications |
@Test
void testGroovletWithNoName() {
withBinding([out: capturedOut, params:[:]]) { shell.evaluate(new File("$groovlet"))
}
assert 'Hello, World!' == content.toString().trim()
}
@Test
void testGroovletWithName() {
withBinding([out: capturedOut, params:[name:'Dolly']]) { shell.evaluate(new File("$groovlet"))
}
assert 'Hello, Dolly!' == content.toString().trim()
}
}
Pass binding variables through the method
The GroovyShellTestCase class instantiates a GroovyShell internally and allows you to pass a map of binding parameters through the withBinding method.
10.2.2Implicit variables in groovlets
The previous example shows that groovlets expect that all the request parameters are bundled into a map called params. Groovlets operate in an environment containing many implicit variables. Table 10.2 shows the complete list.
Table 10.2 Implicit variables available in groovlets
Variable |
Represents |
Notes |
|
|
|
request |
ServletRequest |
|
response |
ServletResponse |
|
session |
getSession(false) |
May be null |
context |
ServletContext |
|
application |
ServletContext (same as context) |
|
params |
|
Map of request parameters |
headers |
|
Map of request/response headers |
out |
response.getWriter() |
|
sout |
response.getOutputStream() |
|
html |
new MarkupBuilder(out) |
|
|
|
|
The previous example used only the params variable. Now I’ll discuss a slightly more elaborate example, which was used in the Groovy Baseball application first presented in chapter 2. The following listing shows the complete source.
www.it-ebooks.info

Easy server-side development with groovlets |
267 |
||||
|
|
|
|
|
|
Listing 10.8 The GameService groovlet from the Groovy Baseball application |
|
||||
import beans.GameResult; |
|
|
|
|
|
import beans.Stadium; |
|
|
|
Setting a |
|
import service.GetGameData; |
|
|
|
|
|
|
|
|
response |
|
|
|
|
|
|
|
|
response.contentType = 'text/xml' |
|
|
|
header |
|
|
|
|
|
|
|
def month = params.month |
|
Access request |
|
||
|
|
||||
def day = params.day |
|
|
|||
|
parameters |
|
|||
def year = params.year |
|
|
|||
|
|
|
|
|
m = month.toInteger() < 10 ? '0' + month : month d = day.toInteger() < 10 ? '0' + day : day
y = year
results = new GetGameData(month:m,day:d,year:y).games
html.games { |
|
Writing out |
|
|
XML data |
||
results.each { g -> |
|||
|
game(
outcome:"$g.away $g.aScore, $g.home $g.hScore", lat:g.stadium.latitude,
lng:g.stadium.longitude
)
}
}
The goal of the GameService groovlet is to get the date provided by the user interface, invoke the getGames method in the GetGameData service, and provide the results to the user in XML form. The groovlet sets the contentType header in the response to XML, retrieves the input parameters representing the requested date, normalizes them to the proper form if necessary, calls the game service, and uses the built-in markup builder to write out the game results as a block of XML.
Using the markup builder to write out XML is helpful here. One of the problems faced by current web applications is that JavaScript code used in the user interface can’t parse the Java or Groovy objects produced by the server side. An intermediate format is needed that both sides can interpret and generate. There are only two realistic options for that: XML and JavaScript Object Notation (JSON). The recent trend has been to use JSON objects as much as possible, but the markup builder inside groovlets makes it easy to produce XML instead. The amount of XML generated by this application is minimal, so it’s not a problem to parse-in the user interface.
PRODUCING XML Use the html markup builder in groovlets to write out XML when needed, not to produce a web page in HTML.
This demonstration is simple, but that’s the point. Groovlets are a convenient way to receive input data, access back-end services, and produce responses or forward the user to a new destination. Because they have a built-in way to convert objects into XML
www.it-ebooks.info

268 |
CHAPTER 10 Building and testing web applications |
(and it wouldn’t be hard to add a JsonBuilder to convert to JSON instead2), they’re ideal as a front-end for RESTful web services.
Lessons learned (groovlets)
1Groovlets are Groovy scripts executed by an embedded servlet.
2Groovlets contain implicit objects for request parameters, the HTTP session, and more.
3Groovlets use builders to generate formatted output.
Before demonstrating the Grails framework, let me now discuss the issue of testing web applications, both in isolation as unit tests and automated integration tests using Gradle.
10.3 Unitand integration-testing web components
Chapter 6 discussed techniques for unit-testing Java and Groovy classes and demonstrated how Groovy’s mock capabilities provide a standard library of mocks and stubs to support unit tests. It’s easy to test individual classes and to run those tests automatically as part of a build process.
Testing is so important that most modern web frameworks consider testability a major design goal, so they try to make the individual components easy to test. For example, one of the major differences between the original Struts framework and the more modern Struts 2, Spring MVC, JSF, or any of a number of others is how their parts are designed with testing in mind. Despite this, testing of web components is far less pervasive than you might expect.
Still, unit-testing and integration-testing web applications is as important as testing anything else in the system, and doing so automatically is critical. Integration-testing a web application by making a tester manually enter data in forms and click links is an extremely expensive and error-prone mechanism. There has to be a better way, and fortunately Groovy helps a lot in that area.
To lay the foundation, however, I’ll begin with a library of mock classes that comes from one of the biggest Java libraries of them all, the Spring framework.
10.3.1Unit-testing servlets with Spring
The Spring framework is one of the most popular open source libraries in the Java world. Chapter 7 on Groovy and Spring discusses it in some detail, but I want to use it here for two reasons: (1) Spring provides a great collection of mock objects for unittesting web applications, and (2) Spring is one of the underlying technologies for Grails, so knowing more about how Spring works helps you use Grails more effectively.
To illustrate the challenge and highlight the dependencies that need to be mocked during testing, let me start with a simple servlet class, written in Java, called HelloServlet:
2 In fact, I helped do exactly that. That’s open source for you; if you get an idea, go do it.
www.it-ebooks.info

Unitand integration-testing web components |
269 |
public class HelloServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().print("Hello, Servlet!");
}
}
Servlets are all created by inheritance, normally by extending javax.servlet.http
.HttpServlet. HttpServlet is an abstract class with no abstract methods. It receives HTTP requests and delegates them to a do method corresponding to each HTTP verb, like doGet, doPost, doPut, doTrace, or doOptions. Each of these methods takes two arguments, one of type HttpServletRequest and one of type HttpServletResponse.
The HelloServlet class overrides the doGet method to respond to HTTP GET requests. It uses the resp argument (an instance of HttpServletResponse) to get the associated output writer, which is used to print to the output stream.
Even in a class this simple, it’s apparent that unit testing is going to be a challenge. As a reminder of what unit testing is all about, let me say this:
UNIT-TESTING WEB COMPONENTS The goal of unit-testing web applications is to run tests outside of a container. This requires mock objects for all the container-provided classes and services.
In this case I need objects representing the two arguments of type HttpServletRequest and HttpServletResponse. In most cases I’ll also need objects representing
HttpSession, ServletContext, and possibly more.
This is where the set of mock classes from the Spring framework helps. The Spring API includes a package called org.springframework.mock.web that, as described in the API, contains “a comprehensive set of Servlet API 2.53 mock objects, targeted at usage with Spring’s web MVC framework.” Fortunately they can be used with any web application, whether it’s based on Spring MVC or not.
The next listing shows a JUnit test for the doGet method of my “Hello, World!” servlet.
Listing 10.9 HelloServletJavaTest: a servlet test class using mock objects
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse;
public class HelloServletJavaTest { @Test
public void testDoGet() {
HelloServlet servlet = new HelloServlet(); MockHttpServletRequest req = new MockHttpServletRequest(); MockHttpServletResponse resp = new MockHttpServletResponse();
3 The mock objects work for Servlet 3.0 as well, with some minor exceptions listed in the JavaDocs.
www.it-ebooks.info