Soap 从映射动态构造闭包?
我正在尝试创建一个发送SOAP请求和获取响应的通用方法。我正在使用Groovy编程,我正在使用库来帮助我解决SOAP问题。下面是一个用于发出SOAP请求并获得响应的示例片段:Soap 从映射动态构造闭包?,soap,groovy,closures,Soap,Groovy,Closures,我正在尝试创建一个发送SOAP请求和获取响应的通用方法。我正在使用Groovy编程,我正在使用库来帮助我解决SOAP问题。下面是一个用于发出SOAP请求并获得响应的示例片段: @Grab('com.github.groovy-wslite:groovy-wslite:1.1.2') import wslite.soap.* SOAPClient client = new SOAPClient('http://www.dneonline.com/calculator.asmx') def res
@Grab('com.github.groovy-wslite:groovy-wslite:1.1.2')
import wslite.soap.*
SOAPClient client = new SOAPClient('http://www.dneonline.com/calculator.asmx')
def response = client.send(SOAPAction: 'http://tempuri.org/Add') {
body {
Add(xmlns: 'http://tempuri.org/') {
intA(x)
intB(y)
}
}
}
一般来说,我的意思是能够动态创建SOAP请求(给定某些信息,如服务/方法名称、方法中包含的参数等)并获得SOAP响应。我是这样想的:
@Grab('com.github.groovy-wslite:groovy-wslite:1.1.2')
import wslite.soap.*
def getResponse(String clientURL, String action, String service, String serviceNamespace, Map parameters, ...) {
SOAPClient client = new SOAPClient(clientURL)
def response = client.send(SOAPAction: action) {
body {
"$service"(xmlns: serviceNameSpace) {
...
}
}
}
}
我的问题在于为请求体构造闭包。例如,在示例中,如果我的方法接收到一个服务
添加
,一个服务名称空间
http://tempuri.org/,以及一个参数映射如下:[intA:x,intB:y]
。。。如何合并所有这些,以便构建此类闭包:
Add(xmlns: 'http://tempuri.org/') {
intA(x)
intB(y)
}
我是Groovy的新手,所以不要太苛刻。如果有更好的方法来实现这个通用方法的概念,我很乐意听到。这个概念类似于。但是我宁愿玩Map
,也不愿玩String
。我没有使用Grails,真的。只是普通的Groovy。简而言之,cfrick是正确的:
[intA: x, intB: y].each{fn,arg -> delegate."$fn"(arg) }
它是如何工作的?
了解其工作原理的一个简单方法是使用假客户端类模拟它:
groovy.util.NodeBuilder
class Client {
def send(String action, Closure closure) {
closure.delegate = new NodeBuilder()
closure()
}
}
def client = new Client()
def response = client.send('http://tempuri.org/Add') {
body {
Add(xmlns: 'http://tempuri.org/') {
intA(1)
intB(2)
}
}
}
assert response.Add[0].@xmlns == 'http://tempuri.org/'
assert response.Add.intA.text() == '1'
assert response.Add.intB.text() == '2'
在上面的示例中,响应
对象是由Groovy的。这只是一种快速的方法,可以对传递给Client.send()
的闭包进行处理
通过这段可测试代码,我将尝试cfrick建议的方法,并验证它是否有效:
def doIt(String action, String service, String serviceNamespace, Map params) {
def client = new Client()
client.send(action) {
body {
"$service"(xmlns: serviceNamespace) {
params.each { method, argument ->
delegate."$method"(argument)
}
}
}
}
}
response = doIt('http://tempuri.org/Add', 'Add', 'http://tempuri.org/', [intA: 1, intB: 2])
assert response.Add[0].@xmlns == 'http://tempuri.org/'
assert response.Add.intA.text() == '1'
assert response.Add.intB.text() == '2'
请求主体
此外,您还可以考虑创建请求正文的过程:
def getRequestBody(String service, String serviceNamespace, Map params) {
{ ->
"$service"(xmlns: serviceNamespace) {
params.each { method, argument ->
delegate."$method"(argument)
}
}
}
}
def doIt(String action, String service, String serviceNamespace, Map params) {
def client = new Client()
client.send(action) {
body(getRequestBody(service, serviceNamespace, params))
}
}
[intA:x,intB:y]每个{fn,arg->delegate.“$fn”(arg)}
都可以吗?现在提问可能有点晚了,但是否可以定义这样一个方法,getRequestBody()
,它将返回所需的body{…}
闭包?除此之外,能够在如下位置调用getRequestBody()
:client.send('http://...“){getRequestBody()}
?如何做到这一点?是的,但不能像client.send那样调用它http://...“){getRequestBody()}
。相反,您可以编写getRequestBody
代码,以便像client.send>一样使用http://...“){body(getRequestBody())}
或client.send('http://...,getRequestBody())
。我添加了第一种方法的演示。