我正在尝试制作一个发送SOAP请求和获取响应的通用方法。我正在使用Groovy编程,我正在使用wslite库来帮助我使用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 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) {
...
}
}
}
}
我的问题在于构造请求体的闭包。例如,如果我的方法收到了service
Add
,serviceNamespace
http://tempuri.org/
和parameter
地图,请执行以下操作:[intA: x, intB: y]
。 ..如何合并所有这些,以便我可以构造这种闭包:
Add(xmlns: 'http://tempuri.org/') {
intA(x)
intB(y)
}
我几乎是Groovy的新手,所以不要太苛刻。如果有更好的方法来实现这种通用方法的概念,我很乐意听到它。该概念类似于this。但我宁愿玩Map
而不是String
。我真的没有使用Grails。简单的Groovy。
答案 0 :(得分:2)
简而言之,cfrick是正确的:
has_many :jobs, dependent: :destroy
查看其工作原理的简单方法是使用假客户端类进行模拟:
[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的NodeBuilder创建。它只是一种快速的方法来处理传递给response
的闭包的原型。
使用这个可测试的代码,我将尝试cfrick建议并验证它是否有效:
Client.send()
此外,您可以分解创建请求正文的过程:
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'