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

Hypermedia |
249 |
The client uses the getLink method with the relation type (next or prev), which returns a Link instance. The getUri method then returns an instance of java.net.URI, which can be followed by the client on the next iteration.21
If you would rather put the links in the body of the response, you need a different approach, as described in the next section.
9.5.3Adding structural links
Structural links in JAX-RS are instances of the Link class inside the entity itself. Converting them to XML or JSON then requires a special serializer, which is provided by the API.
Here’s the Person class, expanded to hold the self, next, and prev links as attributes:
@XmlRootElement
@EqualsAndHashCode class Person {
Long id String first String last
@XmlJavaTypeAdapter(JaxbAdapter) Link prev
@XmlJavaTypeAdapter(JaxbAdapter) Link self
@XmlJavaTypeAdapter(JaxbAdapter) Link next
}
The prev, self, and next links are instances of the javax.ws.rs.core.Link class, as before. Link.JaxbAdapter is an inner class that tells JAXB how to serialize the links.
Setting the values of the link references is done in the resource, this time using an interesting Groovy mechanism:
Response findById(@PathParam("id") long id) { Person p = dao.findById(id) getLinks(id).each { link ->
p."${link.rel}" = link
}
}
The same getLinks private method is used as in the headers section, but this time the links are added to the Person instance. By calling link.rel (which calls the getRel method) and injecting the result into a string, the effect is to call p.self, p.next, or p.prev, as the case may be. In each case, that will call the associated setter method and assign the attribute to the link on the right-hand side.
21I have to mention that this is probably one of the only times in the last decade that I really could have used a do/while loop. Ironically, that’s just about the only Java construct not supported by Groovy.
www.it-ebooks.info
250 |
CHAPTER 9 RESTful web services |
A test of the structural links using the RESTClient looks like this:
def 'structural and transitional links for kirk are correct'() { when:
def response = client.get(path: 'people/3')
then:
'James Kirk' == "$response.data.first $response.data.last" response.getHeaders('Link').each { println it }
assert response.data.prev.href == 'http://localhost:1234/people/2' assert response.data.self.href == 'http://localhost:1234/people/3' assert response.data.next.href == 'http://localhost:1234/people/4'
}
The response wraps a Person instance, accessed by calling getData. Then the individual links are retrieved as the prev, self, and next properties. The result is a Link instance whose getHref method can be used to verify the links.
There’s only one problem, and it’s more of a nuisance than anything else. In the Rotten Tomatoes example at the beginning of the hypermedia section, the links were not top-level attributes of the movies. Instead, each movie representation contained a JSON object whose key was links, and which contained the list of individual links and relations. Here’s the snippet from the Rotten Tomatoes response:
"links": {
"self": "http://api.rottentomatoes.com/.../771190753.json", "cast": "http://api.rottentomatoes.com/.../771190753/cast.json", "clips": "http://api.rottentomatoes.com/.../771190753/clips.json",
"reviews": "http://api.rottentomatoes.com/.../771190753/reviews.json", "similar": "http://api.rottentomatoes.com/.../771190753/similar.json"
}
In the JAX-RS approach using the serializer, the relation is the attribute name. What if I want to make a collection of links as shown in the movie example? For that I need to take control of the serialization process.
9.5.4Using a JsonBuilder to control the output
To customize output generation, JAX-RS includes an interface called javax.ws.rs.ext
.MessageBodyWriter<T>. This interface is the contract for converting a Java type into a stream. It contains three methods to be implemented.
The first method is called isWriteable, and it returns true for types supported by this writer. For the Person class the implementation is simple:
boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
type == Person && mediaType == MediaType.APPLICATION_JSON_TYPE
}
The method returns true only for Person instances and only if the specified media type is JSON.
The second method is called getSize, and it’s deprecated in JAX-RS 2.0. Its implementation is supposed to return -1:
www.it-ebooks.info

Hypermedia |
251 |
long getSize(Person t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return -1;
}
The writeTo method does all the work. Here I use groovy.json.JsonBuilder to generate the output in the form I want, as shown in the following listing.
Listing 9.9 Using a JsonBuilder to produce nested links
void writeTo(Person t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException,
WebApplicationException {
def builder = new JsonBuilder() builder {
id t.id
first t.first last t.last
links { if (t.prev) {
prev t.prev.toString()
}
self t.self.toString() if (t.next) {
next t.next.toString()
}
}
}
entityStream.write(builder.toString().bytes)
}
Conversion to bytes to write to the output stream
One special quirk is notable here. The method calls toString on the individual Link instances. As the JavaDocs for Link make clear, the toString and valueOf(String) methods in Link are used to convert to and from strings.
The MessageBodyReader interface is quite similar. In that case there are only two methods: isReadable and readFrom. The implementation of isReadable is the same as the isWriteable method:
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
type == Person && mediaType == MediaType.APPLICATION_JSON_TYPE
}
The readFrom method uses a JsonSlurper to convert string input into a Person, as shown in the next listing.
Listing 9.10 Parsing a Person instance from a string
public Person readFrom(Class<Person> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders,
www.it-ebooks.info

252 CHAPTER 9 RESTful web services
InputStream entityStream)
throws IOException, WebApplicationException {
def json = new JsonSlurper().parseText(entityStream.text)
Person p = new Person(id:json.id, first:json.first, last:json.last) if (json.links) {
p.prev = Link.valueOf(json.links.prev) p.self = Link.valueOf(json.links.self) p.next = Link.valueOf(json.links.next)
}
return p
}
The readFrom method uses the JsonSlurper’s parseText method to convert the input text data into a JSON object and then instantiates a Person based on the resulting properties. If links exist in the body, they’re converted using the valueOf method.
To use the MessageBodyWriter, I need to add an @Provider annotation to the implementation class and make sure it’s loaded in the application. The latter is done by adding the provider to the MyApplication class:
public class MyApplication extends ResourceConfig { public MyApplication() {
super(PersonResource.class, PersonProvider.class, JacksonFeature.class);
}
}
In this case both the PersonProvider and the JacksonFeature are used. The Person provider converts individual Person instances to JSON, and the JacksonFeature handles collections. A test of the resulting structure looks like this:
def 'transitional links for kirk are correct'() { when:
def response = client.get(path: 'people/3')
then:
'James Kirk' == "$response.data.first $response.data.last" Link.valueOf(response.data.links.prev).uri ==
'http://localhost:1234/people/2'.toURI() Link.valueOf(response.data.links.self).uri == 'http://localhost:1234/people/3'.toURI() Link.valueOf(response.data.links.next).uri == 'http://localhost:1234/people/4'.toURI()
}
The response body now has a links element, which contains prev, self, and next as child elements.
Lessons learned (hypermedia)
1JAX-RS mostly ignores hypermedia but does make some methods available for it.
2Transitional link headers are added by the link and links methods in
ResponseBuilder.
www.it-ebooks.info