I'm familiar with normal groovy closures like these
def printSum = {a,b ->
println a+b
}
printSum(5,7) // 12
However, I came across code from SpringWS plugin that I have a hard time understanding:
def withEndpointRequest = { url, payload ->
def writer = new StringWriter()
def request = new MarkupBuilder(writer)
payload.delegate = request
payload.call()
def webServiceTemplate = new WebServiceTemplate()
def response = webServiceTemplate.sendToEndpoint(url, writer.toString())
new XmlSlurper().parseText(response)
}
I understand that above is a closure.
It is being used like this:
def namespace = "http://www.myveryimportantcompany.com/hr/schemas"
def serviceURL = "http://localhost:8080/myapp/services"
def response = withEndpointRequest(serviceURL) {
HolidayRequest(xmlns: namespace) {
Holiday {
StartDate("2006-07-03")
EndDate("2006-07-07")
}
Employee {
Number("42")
FirstName("Russ")
LastName("Miles")
}
}
}
if serviceURL is being passed in then where is the payload?
Can someone please explain this snippet in some detail?
In the above implementation, withEndpointRequest is a closure which takes two parameters.
withEndpointRequest(String serviceUrl, Closure payload).
When you are using withEndpointRequest from your client, you are actually doing
def namespace = "http://www.myveryimportantcompany.com/hr/schemas"
def serviceURL = "http://localhost:8080/myapp/services"
def payload = {
HolidayRequest(xmlns: namespace) {
Holiday {
StartDate("2006-07-03")
EndDate("2006-07-07")
}
Employee {
Number("42")
FirstName("Russ")
LastName("Miles")
}
}
}
def response = withEndpointRequest(serviceURL, payload)
The above was made groovier by declaring the closure inline with withEndpointRequest.
The above can also be written as
def response = withEndpointRequest(serviceURL, {
//payload goes here as an inline closure as the second parameter
HolidayRequest(xmlns: namespace) {
Holiday {
StartDate("2006-07-03")
EndDate("2006-07-07")
}
Employee {
Number("42")
FirstName("Russ")
LastName("Miles")
}
}
})
which is less verbose. Finally, it can be streamlined and made more groovier by writing as
def response = withEndpointRequest(serviceURL) {
HolidayRequest(xmlns: namespace) {
Holiday {
StartDate("2006-07-03")
EndDate("2006-07-07")
}
Employee {
Number("42")
FirstName("Russ")
LastName("Miles")
}
}
}
One point to note here is that the Closure payload is the last parameter.
Now, note that the closure (payload) is not invoked until payload.call() is invoked as mentioned in your question inside SpringWS plugin.
Have a look at Closures as Method Arguments.
I hope I was able to convey what you wanted to understand. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With