Here's the scenario: I upload a zip file to the service so that it can use the data in that file to populate some things (see my post Groovy, RESTClient, and PUTting zip files for one way to get RESTClient to handle zip files). I watch the log on the server and see that it's handling that file just fine; however, my Groovy script errors out! What's going on?
Here's what the Groovy code looked like at this point:
def file = new File("data_file.zip")
def rest = new RESTClient( 'http://localhost:8080/server/rest/' )
rest.encoder.'application/zip' = { ... handle zip files ... }
rest.put( path: "data/data_file.zip", body: file, requestContentType: 'application/zip' )
It turns out that the RESTful service, once it gets the file, just sends back an HTTP "201 Created" response code. No body to the response at all because, really, there's none needed. However, by default, the RESTClient put() method wants a response body to parse and return, so it throws a NullPointerException when it tries to parse that "nothing".
Since I didn't see a way of telling RESTClient not to expect a response body, I could have just lived with the exception, catching it and moving along. But the exception was being thrown before the response object was passed back, I couldn't even check the status of my request to see if the request was successful or if there were problems. Fortunately, RESTClient is really just a set of convenience wrappers around the main HTTPBuilder, so I was able to implement my request using HTTPBuilder.
HTTPBuilder has the nice feature of allowing you to assign different response handlers to different HTTP response codes, so I could basically tell it not to bother trying to parse '201' responses and just print a "success" message. Here's how I ended up setting up the PUT request using HTTPBuilder:
import groovyx.net.http.HTTPBuilder
import groovyx.net.http.Method
def file = new File("data_file.zip")
def http = new HTTPBuilder('http://localhost:8080/server/rest/')
http.encoder.'application/zip' = { ... handle zip file ... }
http.request(Method.PUT) { req ->
uri.path = 'data/data_file.zip'
send("application/zip", file)
response.'201' = { resp ->
println resp.status
}
response.success = { resp, object ->
println resp.status
}
response.failure = { resp ->
println resp.statusLine
}
}
Of course, we could do a lot more with the response objects, but at this point, all we want to know is whether our request failed or succeeded, without having to worry about a response body. While it's definitely not as convenient as RESTClient, with the HTTPBuilder implementation in place, the file uploaded just fine, and there were no errors on the Groovy end of things.